diff --git a/DeDRM_Macintosh_Application/DeDRM ReadMe.rtf b/DeDRM_Macintosh_Application/DeDRM ReadMe.rtf
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist
old mode 100644
new mode 100755
index d8c82fa..cfd9fcc
--- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist
+++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist
@@ -24,19 +24,19 @@
CFBundleExecutable
droplet
CFBundleGetInfoString
- DeDRM AppleScript 6.0.4. Written 2010–2013 by Apprentice Alf and others.
+ DeDRM AppleScript 6.0.8. Written 2010–2013 by Apprentice Alf and others.
CFBundleIconFile
DeDRM
CFBundleIdentifier
com.apple.ScriptEditor.id.707CCCD5-0C6C-4BEB-B67C-B6E866ADE85A
CFBundleInfoDictionaryVersion
- 6.0
+ 6.0.8
CFBundleName
DeDRM
CFBundlePackageType
APPL
CFBundleShortVersionString
- 6.0.4
+ 6.0.8
CFBundleSignature
dplt
LSRequiresCarbon
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/PkgInfo b/DeDRM_Macintosh_Application/DeDRM.app/Contents/PkgInfo
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM Progress Source.zip b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM Progress Source.zip
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM Progress.app/Contents/Info.plist b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM Progress.app/Contents/Info.plist
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM Progress.app/Contents/PkgInfo b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM Progress.app/Contents/PkgInfo
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM Progress.app/Contents/Resources/DeDRM Progress.icns b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM Progress.app/Contents/Resources/DeDRM Progress.icns
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM Progress.app/Contents/Resources/English.lproj/InfoPlist.strings b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM Progress.app/Contents/Resources/English.lproj/InfoPlist.strings
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM Progress.app/Contents/Resources/English.lproj/MainMenu.nib b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM Progress.app/Contents/Resources/English.lproj/MainMenu.nib
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM Progress.app/Contents/Resources/Scripts/Window.scpt b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM Progress.app/Contents/Resources/Scripts/Window.scpt
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM.icns b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM.icns
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM_Adobe Digital Editions Key_Help.htm b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM_Adobe Digital Editions Key_Help.htm
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM_Barnes and Noble Key_Help.htm b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM_Barnes and Noble Key_Help.htm
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM_EInk Kindle Serial Number_Help.htm b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM_EInk Kindle Serial Number_Help.htm
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM_Help.htm b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM_Help.htm
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM_Kindle for Mac and PC Key_Help.htm b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM_Kindle for Mac and PC Key_Help.htm
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM_Mobipocket PID_Help.htm b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM_Mobipocket PID_Help.htm
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM_eReader Key_Help.htm b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/DeDRM_eReader Key_Help.htm
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/Scripts/main.scpt b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/Scripts/main.scpt
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py
old mode 100644
new mode 100755
index 1c931a4..dd272c8
--- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py
+++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py
@@ -27,14 +27,21 @@
# Revision history:
# 6.0.0 - Initial release
# 6.0.1 - Bug Fixes for Windows App, Kindle for Mac and Windows Adobe Digital Editions
-# 6.0.2 - Restored call to Wine to get Kindle for PC keys
+# 6.0.2 - Restored call to Wine to get Kindle for PC keys, added for ADE
+# 6.0.3 - Fixes for Kindle for Mac and Windows non-ascii user names
+# 6.0.4 - Fixes for stand-alone scripts and applications
+# and pdb files in plugin and initial conversion of prefs.
+# 6.0.5 - Fix a key issue
+# 6.0.6 - Fix up an incorrect function call
+# 6.0.7 - Error handling for incomplete PDF metadata
+# 6.0.8 - Fixes a Wine key issue and topaz support
"""
Decrypt DRMed ebooks.
"""
PLUGIN_NAME = u"DeDRM"
-PLUGIN_VERSION_TUPLE = (6, 0, 2)
+PLUGIN_VERSION_TUPLE = (6, 0, 8)
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'
@@ -213,10 +220,10 @@ def ePubDecrypt(self,path_to_ebook):
else: # linux
from wineutils import WineGetKeys
- scriptpath = os.join(self.alfdir,u"adobekey.py")
+ scriptpath = os.path.join(self.alfdir,u"adobekey.py")
defaultkeys = WineGetKeys(scriptpath, u".der",dedrmprefs['adobewineprefix'])
- self.default_key = default_keys[0]
+ self.default_key = defaultkeys[0]
except:
traceback.print_exc()
self.default_key = u""
@@ -308,8 +315,8 @@ def PDFDecrypt(self,path_to_ebook):
try:
from wineutils import WineGetKeys
- scriptpath = os.join(self.alfdir,u"adobekey.py")
- defaultkeys = self.WineGetKeys(scriptpath, u".der",dedrmprefs['adobewineprefix'])
+ scriptpath = os.path.join(self.alfdir,u"adobekey.py")
+ defaultkeys = WineGetKeys(scriptpath, u".der",dedrmprefs['adobewineprefix'])
except:
pass
@@ -386,8 +393,8 @@ def KindleMobiDecrypt(self,path_to_ebook):
else: # linux
from wineutils import WineGetKeys
- scriptpath = os.join(self.alfdir,u"kindlekey.py")
- defaultkeys = self.WineGetKeys(scriptpath, u".k4i",dedrmprefs['kindlewineprefix'])
+ scriptpath = os.path.join(self.alfdir,u"kindlekey.py")
+ defaultkeys = WineGetKeys(scriptpath, u".k4i",dedrmprefs['kindlewineprefix'])
except:
pass
@@ -426,7 +433,7 @@ def eReaderDecrypt(self,path_to_ebook):
import calibre_plugins.dedrm.prefs as prefs
import calibre_plugins.dedrm.erdr2pml
- dedrmrefs = prefs.DeDRM_Prefs()
+ dedrmprefs = prefs.DeDRM_Prefs()
# Attempt to decrypt epub with each encryption key (generated or provided).
for keyname, userkey in dedrmprefs['ereaderkeys'].items():
keyname_masked = u"".join((u'X' if (x.isdigit()) else x) for x in keyname)
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/adobekey.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/adobekey.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/android.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/android.py
new file mode 100755
index 0000000..ddb94f5
--- /dev/null
+++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/android.py
@@ -0,0 +1,157 @@
+#!/usr/bin/env python
+#fileencoding: utf-8
+
+import os
+import sys
+import zlib
+import tarfile
+from hashlib import md5
+from cStringIO import StringIO
+from binascii import a2b_hex, b2a_hex
+
+STORAGE = 'AmazonSecureStorage.xml'
+
+class AndroidObfuscation(object):
+ '''AndroidObfuscation
+ For the key, it's written in java, and run in android dalvikvm
+ '''
+
+ key = a2b_hex('0176e04c9408b1702d90be333fd53523')
+
+ def encrypt(self, plaintext):
+ cipher = self._get_cipher()
+ padding = len(self.key) - len(plaintext) % len(self.key)
+ plaintext += chr(padding) * padding
+ return b2a_hex(cipher.encrypt(plaintext))
+
+ def decrypt(self, ciphertext):
+ cipher = self._get_cipher()
+ plaintext = cipher.decrypt(a2b_hex(ciphertext))
+ return plaintext[:-ord(plaintext[-1])]
+
+ def _get_cipher(self):
+ try:
+ from Crypto.Cipher import AES
+ return AES.new(self.key)
+ except ImportError:
+ from aescbc import AES, noPadding
+ return AES(self.key, padding=noPadding())
+
+class AndroidObfuscationV2(AndroidObfuscation):
+ '''AndroidObfuscationV2
+ '''
+
+ count = 503
+ password = 'Thomsun was here!'
+
+ def __init__(self, salt):
+ key = self.password + salt
+ for _ in range(self.count):
+ key = md5(key).digest()
+ self.key = key[:8]
+ self.iv = key[8:16]
+
+ def _get_cipher(self):
+ try :
+ from Crypto.Cipher import DES
+ return DES.new(self.key, DES.MODE_CBC, self.iv)
+ except ImportError:
+ from python_des import Des, CBC
+ return Des(self.key, CBC, self.iv)
+
+def parse_preference(path):
+ ''' parse android's shared preference xml '''
+ storage = {}
+ read = open(path)
+ for line in read:
+ line = line.strip()
+ # value
+ if line.startswith(' adb backup com.amazon.kindle
+ '''
+ output = None
+ read = open(path, 'rb')
+ head = read.read(24)
+ if head == 'ANDROID BACKUP\n1\n1\nnone\n':
+ output = StringIO(zlib.decompress(read.read()))
+ read.close()
+
+ if not output:
+ return False
+
+ tar = tarfile.open(fileobj=output)
+ for member in tar.getmembers():
+ if member.name.strip().endswith(STORAGE):
+ write = open(STORAGE, 'w')
+ write.write(tar.extractfile(member).read())
+ write.close()
+ break
+
+ return True
+
+__all__ = [ 'get_storage', 'get_serials', 'parse_preference',
+ 'AndroidObfuscation', 'AndroidObfuscationV2', 'STORAGE']
+
+if __name__ == '__main__':
+ print get_serials()
\ No newline at end of file
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/android_readme.txt b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/android_readme.txt
new file mode 100755
index 0000000..9e7d035
--- /dev/null
+++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/android_readme.txt
@@ -0,0 +1,6 @@
+1.1 get AmazonSecureStorage.xml from /data/data/com.amazon.kindle/shared_prefs/AmazonSecureStorage.xml
+
+1.2 on android 4.0+, run `adb backup com.amazon.kindle` from PC will get backup.ab
+ now android.py can convert backup.ab to AmazonSecureStorage.xml
+
+2. run `k4mobidedrm.py -a AmazonSecureStorage.xml '
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/config.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/config.py
old mode 100644
new mode 100755
index f159a9f..d8d5390
--- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/config.py
+++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/config.py
@@ -6,7 +6,7 @@
__license__ = 'GPL v3'
# Standard Python modules.
-import os, traceback
+import os, traceback, json
# PyQT4 modules (part of calibre).
from PyQt4.Qt import (Qt, QWidget, QHBoxLayout, QVBoxLayout, QLabel, QLineEdit,
@@ -178,8 +178,8 @@ def __init__(self, parent, key_type_name, plugin_keys, create_key, keyfile_ext =
self.create_key = create_key
self.keyfile_ext = keyfile_ext
self.import_key = (keyfile_ext != u"")
- self.binary_file = (keyfile_ext == u".der")
- self.json_file = (keyfile_ext == u".k4i")
+ self.binary_file = (keyfile_ext == u"der")
+ self.json_file = (keyfile_ext == u"k4i")
self.wineprefix = wineprefix
self.setWindowTitle("{0} {1}: Manage {2}s".format(PLUGIN_NAME, PLUGIN_VERSION, self.key_type_name))
@@ -676,7 +676,7 @@ def __init__(self, parent=None,):
from calibre_plugins.dedrm.adobekey import adeptkeys
defaultkeys = adeptkeys()
- else: # linux
+ else: # linux
from wineutils import WineGetKeys
scriptpath = os.path.join(parent.parent.alfdir,u"adobekey.py")
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/description.rtfd/TXT.rtf b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/description.rtfd/TXT.rtf
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/droplet.rsrc b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/droplet.rsrc
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/epubtest.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/epubtest.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/erdr2pml.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/erdr2pml.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/flatxml2html.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/flatxml2html.py
index 4d83368..991591b 100755
--- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/flatxml2html.py
+++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/flatxml2html.py
@@ -458,7 +458,11 @@ def buildParagraph(self, pclass, pdesc, type, regtype) :
(wtype, num) = pdesc[j]
if wtype == 'ocr' :
- word = self.ocrtext[num]
+ try:
+ word = self.ocrtext[num]
+ except:
+ word = ""
+
sep = ' '
if handle_links:
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ignobleepub.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ignobleepub.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ignoblekeygen.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ignoblekeygen.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptepub.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptepub.py
old mode 100644
new mode 100755
index 225ffa7..f8181cb
--- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptepub.py
+++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptepub.py
@@ -3,7 +3,7 @@
from __future__ import with_statement
-# ineptepub.pyw, version 5.9
+# ineptepub.pyw, version 6.1
# Copyright © 2009-2010 by i♥cabbages
# Released under the terms of the GNU General Public Licence, version 3
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptpdf.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptpdf.py
old mode 100644
new mode 100755
index 797db60..1986e20
--- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptpdf.py
+++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptpdf.py
@@ -51,14 +51,15 @@
# 7.12 - Revised to allow use in calibre plugins to eliminate need for duplicate code
# 7.13 - Fixed erroneous mentions of ineptepub
# 7.14 - moved unicode_argv call inside main for Windows DeDRM compatibility
-# 8.0 - Work if TkInter is missing
+# 8.0 - Work if TkInter is missing
+# 8.0.1 - Broken Metadata fix.
"""
Decrypts Adobe ADEPT-encrypted PDF files.
"""
__license__ = 'GPL v3'
-__version__ = "8.0"
+__version__ = "8.0.1"
import sys
import os
@@ -949,8 +950,11 @@ def nextobject(self, direct=False):
try:
(pos, objs) = self.end_type('d')
if len(objs) % 2 != 0:
- raise PSSyntaxError(
- 'Invalid dictionary construct: %r' % objs)
+ print "Incomplete dictionary construct"
+ objs.append("") # this isn't necessary.
+ # temporary fix. is this due to rental books?
+ # raise PSSyntaxError(
+ # 'Invalid dictionary construct: %r' % objs)
d = dict((literal_name(k), v) \
for (k,v) in choplist(2, objs))
self.push((pos, d))
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/k4mobidedrm.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/k4mobidedrm.py
old mode 100644
new mode 100755
index 0e426a1..504105b
--- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/k4mobidedrm.py
+++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/k4mobidedrm.py
@@ -80,10 +80,12 @@ class DrmException(Exception):
from calibre_plugins.dedrm import mobidedrm
from calibre_plugins.dedrm import topazextract
from calibre_plugins.dedrm import kgenpids
+ from calibre_plugins.dedrm import android
else:
import mobidedrm
import topazextract
import kgenpids
+ import android
# Wrap a stream so that output gets flushed immediately
# and also make sure that any unicode strings get
@@ -188,7 +190,7 @@ def fixup(m):
def GetDecryptedBook(infile, kDatabases, serials, pids, starttime = time.time()):
# handle the obvious cases at the beginning
if not os.path.isfile(infile):
- raise DRMException (u"Input file does not exist.")
+ raise DrmException(u"Input file does not exist.")
mobi = True
magic3 = open(infile,'rb').read(3)
@@ -273,7 +275,7 @@ def decryptBook(infile, outdir, kDatabaseFiles, serials, pids):
def usage(progname):
print u"Removes DRM protection from Mobipocket, Amazon KF8, Amazon Print Replica and Amazon Topaz ebooks"
print u"Usage:"
- print u" {0} [-k ] [-p ] [-s ] ".format(progname)
+ print u" {0} [-k ] [-p ] [-s ] [ -a ] ".format(progname)
#
# Main
@@ -284,7 +286,7 @@ def cli_main():
print u"K4MobiDeDrm v{0}.\nCopyright © 2008-2013 The Dark Reverser et al.".format(__version__)
try:
- opts, args = getopt.getopt(argv[1:], "k:p:s:")
+ opts, args = getopt.getopt(argv[1:], "k:p:s:a:")
except getopt.GetoptError, err:
print u"Error in options or arguments: {0}".format(err.args[0])
usage(progname)
@@ -312,6 +314,11 @@ def cli_main():
if a == None :
raise DrmException("Invalid parameter for -s")
serials = a.split(',')
+ if o == '-a':
+ if a == None:
+ continue
+ serials.extend(android.get_serials(a))
+ serials.extend(android.get_serials())
# try with built in Kindle Info files if not on Linux
k4 = not sys.platform.startswith('linux')
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kgenpids.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kgenpids.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kindlekey.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kindlekey.py
old mode 100644
new mode 100755
index f58e973..8852769
--- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kindlekey.py
+++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kindlekey.py
@@ -19,6 +19,7 @@
# 1.6 - Fixed a problem getting the disk serial numbers
# 1.7 - Work if TkInter is missing
# 1.8 - Fixes for Kindle for Mac, and non-ascii in Windows user names
+# 1.9 - Fixes for Unicode in Windows user names
"""
@@ -26,7 +27,7 @@
"""
__license__ = 'GPL v3'
-__version__ = '1.8'
+__version__ = '1.9'
import sys, os, re
from struct import pack, unpack, unpack_from
@@ -907,18 +908,34 @@ def CryptUnprotectData(indata, entropy, flags):
return CryptUnprotectData
CryptUnprotectData = CryptUnprotectData()
+ # Returns Environmental Variables that contain unicode
+ def getEnvironmentVariable(name):
+ import ctypes
+ name = unicode(name) # make sure string argument is unicode
+ n = ctypes.windll.kernel32.GetEnvironmentVariableW(name, None, 0)
+ if n == 0:
+ return None
+ buf = ctypes.create_unicode_buffer(u'\0'*n)
+ ctypes.windll.kernel32.GetEnvironmentVariableW(name, buf, n)
+ return buf.value
# Locate all of the kindle-info style files and return as list
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
+ # or the python interface to the 32 vs 64 bit registry is broken
path = ""
if 'LOCALAPPDATA' in os.environ.keys():
- path = os.environ['LOCALAPPDATA']
+ # Python 2.x does not return unicode env. Use Python 3.x
+ path = winreg.ExpandEnvironmentStrings(u"%LOCALAPPDATA%")
+ # this is just another alternative.
+ # path = getEnvironmentVariable('LOCALAPPDATA')
+ if not os.path.isdir(path):
+ path = ""
else:
# User Shell Folders show take precedent over Shell Folders if present
try:
+ # this will still break
regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\")
path = winreg.QueryValueEx(regkey, 'Local AppData')[0]
if not os.path.isdir(path):
@@ -937,13 +954,14 @@ def getKindleInfoFiles():
if path == "":
print ('Could not find the folder in which to look for kinfoFiles.')
else:
- print('searching for kinfoFiles in ' + path)
+ # Probably not the best. To Fix (shouldn't ignore in encoding) or use utf-8
+ print(u'searching for kinfoFiles in ' + path.encode('ascii', 'ignore'))
# look for (K4PC 1.9.0 and later) .kinf2011 file
kinfopath = path +'\\Amazon\\Kindle\\storage\\.kinf2011'
if os.path.isfile(kinfopath):
found = True
- print('Found K4PC 1.9+ kinf2011 file: ' + kinfopath)
+ print('Found K4PC 1.9+ kinf2011 file: ' + kinfopath.encode('ascii','ignore'))
kInfoFiles.append(kinfopath)
# look for (K4PC 1.6.0 and later) rainier.2.1.1.kinf file
@@ -1142,7 +1160,7 @@ def getDBfromFile(kInfoFile):
cleartext = CryptUnprotectData(encryptedValue, entropy, 1)
DB[keyname] = cleartext
- if 'MazamaRandomNumber' in DB and 'kindle.account.tokens' in DB:
+ if 'kindle.account.tokens' in DB:
print u"Decrypted key file using IDString '{0:s}' and UserName '{1:s}'".format(GetIDString(), GetUserName().decode("latin-1"))
# store values used in decryption
DB['IDString'] = GetIDString()
@@ -1758,7 +1776,7 @@ def getDBfromFile(kInfoFile):
break
except:
pass
- if 'MazamaRandomNumber' in DB and 'kindle.account.tokens' in DB:
+ if 'kindle.account.tokens' in DB:
# store values used in decryption
print u"Decrypted key file using IDString '{0:s}' and UserName '{1:s}'".format(IDString, GetUserName())
DB['IDString'] = IDString
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kindlepid.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kindlepid.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/mobidedrm.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/mobidedrm.py
old mode 100644
new mode 100755
index 7b69edc..89cc695
--- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/mobidedrm.py
+++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/mobidedrm.py
@@ -156,6 +156,8 @@ def PC1(key, src, decryption=True):
return Pukall_Cipher().PC1(key,src,decryption)
except NameError:
pass
+ except TypeError:
+ pass
# use slow python version, since Pukall_Cipher didn't load
sum1 = 0;
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/openssl_des.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/openssl_des.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/plugin-import-name-dedrm.txt b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/plugin-import-name-dedrm.txt
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/prefs.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/prefs.py
index 2c8c665..05065ac 100755
--- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/prefs.py
+++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/prefs.py
@@ -114,7 +114,7 @@ def parseeReaderString(keystuff):
# Generate eReader user key from name and credit card number.
keyname = u"{0}_{1}".format(name.strip(),cc.strip()[-4:])
keyvalue = getuser_key(name,cc).encode('hex')
- userkeysappend([keyname,keyvalue])
+ userkeys.append([keyname,keyvalue])
except Exception, e:
traceback.print_exc()
print e.args[0]
@@ -231,21 +231,20 @@ def getConfigFiles(extension, encoding = None):
dedrmprefs.addnamedvaluetoprefs('bandnkeys', name, value)
addedkeycount = len(dedrmprefs['bandnkeys'])-priorkeycount
if addedkeycount > 0:
- print u"{0} v{1}: {2:d} Barnes and Noble {3} imported from config folder.".format(PLUGIN_NAME, PLUGIN_VERSION, ignoblecount, u"key file" if ignoblecount==1 else u"key files")
+ print u"{0} v{1}: {2:d} Barnes and Noble {3} imported from config folder.".format(PLUGIN_NAME, PLUGIN_VERSION, addedkeycount, u"key file" if addedkeycount==1 else u"key files")
# Make the json write all the prefs to disk
dedrmprefs.writeprefs(False)
# get any .der files in the config dir
priorkeycount = len(dedrmprefs['adeptkeys'])
adeptfilekeys = getConfigFiles('.der','hex')
- ineptcount = addConfigFiles('.der', 'adeptkeys')
for keypair in adeptfilekeys:
name = keypair[0]
value = keypair[1]
dedrmprefs.addnamedvaluetoprefs('adeptkeys', name, value)
addedkeycount = len(dedrmprefs['adeptkeys'])-priorkeycount
if addedkeycount > 0:
- print u"{0} v{1}: {2:d} Adobe Adept {3} imported from config folder.".format(PLUGIN_NAME, PLUGIN_VERSION, ineptcount, u"keyfile" if ineptcount==1 else u"keyfiles")
+ print u"{0} v{1}: {2:d} Adobe Adept {3} imported from config folder.".format(PLUGIN_NAME, PLUGIN_VERSION, addedkeycount, u"keyfile" if addedkeycount==1 else u"keyfiles")
# Make the json write all the prefs to disk
dedrmprefs.writeprefs(False)
@@ -280,7 +279,7 @@ def getConfigFiles(extension, encoding = None):
if addedserialcount > 0:
print u"{0} v{1}: {2:d} {3} imported from Kindle plugin preferences".format(PLUGIN_NAME, PLUGIN_VERSION, addedserialcount, u"serial number" if addedserialcount==1 else u"serial numbers")
try:
- if kindleprefs['wineprefix'] != "":
+ if 'wineprefix' in kindleprefs and kindleprefs['wineprefix'] != "":
dedrmprefs.set('adobewineprefix',kindleprefs['wineprefix'])
dedrmprefs.set('kindlewineprefix',kindleprefs['wineprefix'])
print u"{0} v{1}: WINEPREFIX ‘(2)’ imported from Kindle plugin preferences".format(PLUGIN_NAME, PLUGIN_VERSION, kindleprefs['wineprefix'])
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/pycrypto_des.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/pycrypto_des.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/python_des.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/python_des.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/scriptinterface.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/scriptinterface.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/stylexml2css.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/stylexml2css.py
old mode 100644
new mode 100755
index c111850..daa108a
--- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/stylexml2css.py
+++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/stylexml2css.py
@@ -178,7 +178,12 @@ def process(self):
if val == "":
val = 0
- if not ((attr == 'hang') and (int(val) == 0)) :
+ if not ((attr == 'hang') and (int(val) == 0)):
+ try:
+ f = float(val)
+ except:
+ print "Warning: unrecognised val, ignoring"
+ val = 0
pv = float(val)/scale
cssargs[attr] = (self.attr_val_map[attr], pv)
keep = True
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/topazextract.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/topazextract.py
old mode 100644
new mode 100755
index 97f6583..fb5eb7a
--- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/topazextract.py
+++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/topazextract.py
@@ -356,7 +356,7 @@ def processBook(self, pidlst):
self.setBookKey(bookKey)
self.createBookDirectory()
- self.extractFiles()
+ self.extractFiles()
print u"Successfully Extracted Topaz contents"
if inCalibre:
from calibre_plugins.dedrm import genbook
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/utilities.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/utilities.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/wineutils.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/wineutils.py
index f8d5f7a..b54db80 100755
--- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/wineutils.py
+++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/wineutils.py
@@ -24,7 +24,7 @@ def WineGetKeys(scriptpath, extension, wineprefix=""):
outdirpath = os.path.join(basepath, u"winekeysdir")
if not os.path.exists(outdirpath):
- os.mkdir(outdirpath)
+ os.makedirs(outdirpath)
if wineprefix != "" and os.path.exists(wineprefix):
cmdline = u"WINEPREFIX=\"{2}\" wine python.exe \"{0}\" \"{1}\"".format(scriptpath,outdirpath,wineprefix)
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/zipfilerugged.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/zipfilerugged.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_Drop_Target.bat b/DeDRM_Windows_Application/DeDRM_App/DeDRM_Drop_Target.bat
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/DeDRM_App.pyw b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/DeDRM_App.pyw
old mode 100644
new mode 100755
index f00b934..7225b6d
--- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/DeDRM_App.pyw
+++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/DeDRM_App.pyw
@@ -10,8 +10,9 @@
# 6.0.2 - Fixed problem with spaces in paths and the bat file
# 6.0.3 - Fix for Windows non-ascii user names
# 6.0.4 - Fix for other potential unicode problems
+# 6.0.5 - Fix typo
-__version__ = '6.0.4'
+__version__ = '6.0.8'
import sys
import os, os.path
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/DeDRM_Adobe Digital Editions Key_Help.htm b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/DeDRM_Adobe Digital Editions Key_Help.htm
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/DeDRM_Barnes and Noble Key_Help.htm b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/DeDRM_Barnes and Noble Key_Help.htm
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/DeDRM_EInk Kindle Serial Number_Help.htm b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/DeDRM_EInk Kindle Serial Number_Help.htm
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/DeDRM_Help.htm b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/DeDRM_Help.htm
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/DeDRM_Kindle for Mac and PC Key_Help.htm b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/DeDRM_Kindle for Mac and PC Key_Help.htm
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/DeDRM_Mobipocket PID_Help.htm b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/DeDRM_Mobipocket PID_Help.htm
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/DeDRM_eReader Key_Help.htm b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/DeDRM_eReader Key_Help.htm
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/__init__.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/__init__.py
old mode 100644
new mode 100755
index 1c931a4..dd272c8
--- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/__init__.py
+++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/__init__.py
@@ -27,14 +27,21 @@
# Revision history:
# 6.0.0 - Initial release
# 6.0.1 - Bug Fixes for Windows App, Kindle for Mac and Windows Adobe Digital Editions
-# 6.0.2 - Restored call to Wine to get Kindle for PC keys
+# 6.0.2 - Restored call to Wine to get Kindle for PC keys, added for ADE
+# 6.0.3 - Fixes for Kindle for Mac and Windows non-ascii user names
+# 6.0.4 - Fixes for stand-alone scripts and applications
+# and pdb files in plugin and initial conversion of prefs.
+# 6.0.5 - Fix a key issue
+# 6.0.6 - Fix up an incorrect function call
+# 6.0.7 - Error handling for incomplete PDF metadata
+# 6.0.8 - Fixes a Wine key issue and topaz support
"""
Decrypt DRMed ebooks.
"""
PLUGIN_NAME = u"DeDRM"
-PLUGIN_VERSION_TUPLE = (6, 0, 2)
+PLUGIN_VERSION_TUPLE = (6, 0, 8)
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'
@@ -213,10 +220,10 @@ def ePubDecrypt(self,path_to_ebook):
else: # linux
from wineutils import WineGetKeys
- scriptpath = os.join(self.alfdir,u"adobekey.py")
+ scriptpath = os.path.join(self.alfdir,u"adobekey.py")
defaultkeys = WineGetKeys(scriptpath, u".der",dedrmprefs['adobewineprefix'])
- self.default_key = default_keys[0]
+ self.default_key = defaultkeys[0]
except:
traceback.print_exc()
self.default_key = u""
@@ -308,8 +315,8 @@ def PDFDecrypt(self,path_to_ebook):
try:
from wineutils import WineGetKeys
- scriptpath = os.join(self.alfdir,u"adobekey.py")
- defaultkeys = self.WineGetKeys(scriptpath, u".der",dedrmprefs['adobewineprefix'])
+ scriptpath = os.path.join(self.alfdir,u"adobekey.py")
+ defaultkeys = WineGetKeys(scriptpath, u".der",dedrmprefs['adobewineprefix'])
except:
pass
@@ -386,8 +393,8 @@ def KindleMobiDecrypt(self,path_to_ebook):
else: # linux
from wineutils import WineGetKeys
- scriptpath = os.join(self.alfdir,u"kindlekey.py")
- defaultkeys = self.WineGetKeys(scriptpath, u".k4i",dedrmprefs['kindlewineprefix'])
+ scriptpath = os.path.join(self.alfdir,u"kindlekey.py")
+ defaultkeys = WineGetKeys(scriptpath, u".k4i",dedrmprefs['kindlewineprefix'])
except:
pass
@@ -426,7 +433,7 @@ def eReaderDecrypt(self,path_to_ebook):
import calibre_plugins.dedrm.prefs as prefs
import calibre_plugins.dedrm.erdr2pml
- dedrmrefs = prefs.DeDRM_Prefs()
+ dedrmprefs = prefs.DeDRM_Prefs()
# Attempt to decrypt epub with each encryption key (generated or provided).
for keyname, userkey in dedrmprefs['ereaderkeys'].items():
keyname_masked = u"".join((u'X' if (x.isdigit()) else x) for x in keyname)
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/activitybar.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/activitybar.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/adobekey.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/adobekey.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/aescbc.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/aescbc.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/alfcrypto.dll b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/alfcrypto.dll
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/alfcrypto.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/alfcrypto.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/alfcrypto64.dll b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/alfcrypto64.dll
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/alfcrypto_src.zip b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/alfcrypto_src.zip
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/android.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/android.py
new file mode 100755
index 0000000..ddb94f5
--- /dev/null
+++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/android.py
@@ -0,0 +1,157 @@
+#!/usr/bin/env python
+#fileencoding: utf-8
+
+import os
+import sys
+import zlib
+import tarfile
+from hashlib import md5
+from cStringIO import StringIO
+from binascii import a2b_hex, b2a_hex
+
+STORAGE = 'AmazonSecureStorage.xml'
+
+class AndroidObfuscation(object):
+ '''AndroidObfuscation
+ For the key, it's written in java, and run in android dalvikvm
+ '''
+
+ key = a2b_hex('0176e04c9408b1702d90be333fd53523')
+
+ def encrypt(self, plaintext):
+ cipher = self._get_cipher()
+ padding = len(self.key) - len(plaintext) % len(self.key)
+ plaintext += chr(padding) * padding
+ return b2a_hex(cipher.encrypt(plaintext))
+
+ def decrypt(self, ciphertext):
+ cipher = self._get_cipher()
+ plaintext = cipher.decrypt(a2b_hex(ciphertext))
+ return plaintext[:-ord(plaintext[-1])]
+
+ def _get_cipher(self):
+ try:
+ from Crypto.Cipher import AES
+ return AES.new(self.key)
+ except ImportError:
+ from aescbc import AES, noPadding
+ return AES(self.key, padding=noPadding())
+
+class AndroidObfuscationV2(AndroidObfuscation):
+ '''AndroidObfuscationV2
+ '''
+
+ count = 503
+ password = 'Thomsun was here!'
+
+ def __init__(self, salt):
+ key = self.password + salt
+ for _ in range(self.count):
+ key = md5(key).digest()
+ self.key = key[:8]
+ self.iv = key[8:16]
+
+ def _get_cipher(self):
+ try :
+ from Crypto.Cipher import DES
+ return DES.new(self.key, DES.MODE_CBC, self.iv)
+ except ImportError:
+ from python_des import Des, CBC
+ return Des(self.key, CBC, self.iv)
+
+def parse_preference(path):
+ ''' parse android's shared preference xml '''
+ storage = {}
+ read = open(path)
+ for line in read:
+ line = line.strip()
+ # value
+ if line.startswith(' adb backup com.amazon.kindle
+ '''
+ output = None
+ read = open(path, 'rb')
+ head = read.read(24)
+ if head == 'ANDROID BACKUP\n1\n1\nnone\n':
+ output = StringIO(zlib.decompress(read.read()))
+ read.close()
+
+ if not output:
+ return False
+
+ tar = tarfile.open(fileobj=output)
+ for member in tar.getmembers():
+ if member.name.strip().endswith(STORAGE):
+ write = open(STORAGE, 'w')
+ write.write(tar.extractfile(member).read())
+ write.close()
+ break
+
+ return True
+
+__all__ = [ 'get_storage', 'get_serials', 'parse_preference',
+ 'AndroidObfuscation', 'AndroidObfuscationV2', 'STORAGE']
+
+if __name__ == '__main__':
+ print get_serials()
\ No newline at end of file
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/android_readme.txt b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/android_readme.txt
new file mode 100755
index 0000000..9e7d035
--- /dev/null
+++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/android_readme.txt
@@ -0,0 +1,6 @@
+1.1 get AmazonSecureStorage.xml from /data/data/com.amazon.kindle/shared_prefs/AmazonSecureStorage.xml
+
+1.2 on android 4.0+, run `adb backup com.amazon.kindle` from PC will get backup.ab
+ now android.py can convert backup.ab to AmazonSecureStorage.xml
+
+2. run `k4mobidedrm.py -a AmazonSecureStorage.xml '
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/argv_utils.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/argv_utils.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/askfolder_ed.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/askfolder_ed.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/config.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/config.py
old mode 100644
new mode 100755
index f159a9f..d8d5390
--- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/config.py
+++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/config.py
@@ -6,7 +6,7 @@
__license__ = 'GPL v3'
# Standard Python modules.
-import os, traceback
+import os, traceback, json
# PyQT4 modules (part of calibre).
from PyQt4.Qt import (Qt, QWidget, QHBoxLayout, QVBoxLayout, QLabel, QLineEdit,
@@ -178,8 +178,8 @@ def __init__(self, parent, key_type_name, plugin_keys, create_key, keyfile_ext =
self.create_key = create_key
self.keyfile_ext = keyfile_ext
self.import_key = (keyfile_ext != u"")
- self.binary_file = (keyfile_ext == u".der")
- self.json_file = (keyfile_ext == u".k4i")
+ self.binary_file = (keyfile_ext == u"der")
+ self.json_file = (keyfile_ext == u"k4i")
self.wineprefix = wineprefix
self.setWindowTitle("{0} {1}: Manage {2}s".format(PLUGIN_NAME, PLUGIN_VERSION, self.key_type_name))
@@ -676,7 +676,7 @@ def __init__(self, parent=None,):
from calibre_plugins.dedrm.adobekey import adeptkeys
defaultkeys = adeptkeys()
- else: # linux
+ else: # linux
from wineutils import WineGetKeys
scriptpath = os.path.join(parent.parent.alfdir,u"adobekey.py")
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/convert2xml.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/convert2xml.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/dialogs.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/dialogs.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/encodebase64.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/encodebase64.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/epubtest.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/epubtest.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/erdr2pml.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/erdr2pml.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/flatxml2html.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/flatxml2html.py
old mode 100644
new mode 100755
index 4d83368..991591b
--- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/flatxml2html.py
+++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/flatxml2html.py
@@ -458,7 +458,11 @@ def buildParagraph(self, pclass, pdesc, type, regtype) :
(wtype, num) = pdesc[j]
if wtype == 'ocr' :
- word = self.ocrtext[num]
+ try:
+ word = self.ocrtext[num]
+ except:
+ word = ""
+
sep = ' '
if handle_links:
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/flatxml2svg.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/flatxml2svg.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/genbook.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/genbook.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ignobleepub.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ignobleepub.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ignoblekeygen.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ignoblekeygen.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptepub.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptepub.py
old mode 100644
new mode 100755
index 225ffa7..f8181cb
--- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptepub.py
+++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptepub.py
@@ -3,7 +3,7 @@
from __future__ import with_statement
-# ineptepub.pyw, version 5.9
+# ineptepub.pyw, version 6.1
# Copyright © 2009-2010 by i♥cabbages
# Released under the terms of the GNU General Public Licence, version 3
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptpdf.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptpdf.py
old mode 100644
new mode 100755
index 797db60..1986e20
--- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptpdf.py
+++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptpdf.py
@@ -51,14 +51,15 @@
# 7.12 - Revised to allow use in calibre plugins to eliminate need for duplicate code
# 7.13 - Fixed erroneous mentions of ineptepub
# 7.14 - moved unicode_argv call inside main for Windows DeDRM compatibility
-# 8.0 - Work if TkInter is missing
+# 8.0 - Work if TkInter is missing
+# 8.0.1 - Broken Metadata fix.
"""
Decrypts Adobe ADEPT-encrypted PDF files.
"""
__license__ = 'GPL v3'
-__version__ = "8.0"
+__version__ = "8.0.1"
import sys
import os
@@ -949,8 +950,11 @@ def nextobject(self, direct=False):
try:
(pos, objs) = self.end_type('d')
if len(objs) % 2 != 0:
- raise PSSyntaxError(
- 'Invalid dictionary construct: %r' % objs)
+ print "Incomplete dictionary construct"
+ objs.append("") # this isn't necessary.
+ # temporary fix. is this due to rental books?
+ # raise PSSyntaxError(
+ # 'Invalid dictionary construct: %r' % objs)
d = dict((literal_name(k), v) \
for (k,v) in choplist(2, objs))
self.push((pos, d))
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/k4mobidedrm.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/k4mobidedrm.py
old mode 100644
new mode 100755
index 0e426a1..504105b
--- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/k4mobidedrm.py
+++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/k4mobidedrm.py
@@ -80,10 +80,12 @@ class DrmException(Exception):
from calibre_plugins.dedrm import mobidedrm
from calibre_plugins.dedrm import topazextract
from calibre_plugins.dedrm import kgenpids
+ from calibre_plugins.dedrm import android
else:
import mobidedrm
import topazextract
import kgenpids
+ import android
# Wrap a stream so that output gets flushed immediately
# and also make sure that any unicode strings get
@@ -188,7 +190,7 @@ def fixup(m):
def GetDecryptedBook(infile, kDatabases, serials, pids, starttime = time.time()):
# handle the obvious cases at the beginning
if not os.path.isfile(infile):
- raise DRMException (u"Input file does not exist.")
+ raise DrmException(u"Input file does not exist.")
mobi = True
magic3 = open(infile,'rb').read(3)
@@ -273,7 +275,7 @@ def decryptBook(infile, outdir, kDatabaseFiles, serials, pids):
def usage(progname):
print u"Removes DRM protection from Mobipocket, Amazon KF8, Amazon Print Replica and Amazon Topaz ebooks"
print u"Usage:"
- print u" {0} [-k ] [-p ] [-s ] ".format(progname)
+ print u" {0} [-k ] [-p ] [-s ] [ -a ] ".format(progname)
#
# Main
@@ -284,7 +286,7 @@ def cli_main():
print u"K4MobiDeDrm v{0}.\nCopyright © 2008-2013 The Dark Reverser et al.".format(__version__)
try:
- opts, args = getopt.getopt(argv[1:], "k:p:s:")
+ opts, args = getopt.getopt(argv[1:], "k:p:s:a:")
except getopt.GetoptError, err:
print u"Error in options or arguments: {0}".format(err.args[0])
usage(progname)
@@ -312,6 +314,11 @@ def cli_main():
if a == None :
raise DrmException("Invalid parameter for -s")
serials = a.split(',')
+ if o == '-a':
+ if a == None:
+ continue
+ serials.extend(android.get_serials(a))
+ serials.extend(android.get_serials())
# try with built in Kindle Info files if not on Linux
k4 = not sys.platform.startswith('linux')
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/kgenpids.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/kgenpids.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/kindlekey.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/kindlekey.py
old mode 100644
new mode 100755
index f58e973..8852769
--- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/kindlekey.py
+++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/kindlekey.py
@@ -19,6 +19,7 @@
# 1.6 - Fixed a problem getting the disk serial numbers
# 1.7 - Work if TkInter is missing
# 1.8 - Fixes for Kindle for Mac, and non-ascii in Windows user names
+# 1.9 - Fixes for Unicode in Windows user names
"""
@@ -26,7 +27,7 @@
"""
__license__ = 'GPL v3'
-__version__ = '1.8'
+__version__ = '1.9'
import sys, os, re
from struct import pack, unpack, unpack_from
@@ -907,18 +908,34 @@ def CryptUnprotectData(indata, entropy, flags):
return CryptUnprotectData
CryptUnprotectData = CryptUnprotectData()
+ # Returns Environmental Variables that contain unicode
+ def getEnvironmentVariable(name):
+ import ctypes
+ name = unicode(name) # make sure string argument is unicode
+ n = ctypes.windll.kernel32.GetEnvironmentVariableW(name, None, 0)
+ if n == 0:
+ return None
+ buf = ctypes.create_unicode_buffer(u'\0'*n)
+ ctypes.windll.kernel32.GetEnvironmentVariableW(name, buf, n)
+ return buf.value
# Locate all of the kindle-info style files and return as list
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
+ # or the python interface to the 32 vs 64 bit registry is broken
path = ""
if 'LOCALAPPDATA' in os.environ.keys():
- path = os.environ['LOCALAPPDATA']
+ # Python 2.x does not return unicode env. Use Python 3.x
+ path = winreg.ExpandEnvironmentStrings(u"%LOCALAPPDATA%")
+ # this is just another alternative.
+ # path = getEnvironmentVariable('LOCALAPPDATA')
+ if not os.path.isdir(path):
+ path = ""
else:
# User Shell Folders show take precedent over Shell Folders if present
try:
+ # this will still break
regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\")
path = winreg.QueryValueEx(regkey, 'Local AppData')[0]
if not os.path.isdir(path):
@@ -937,13 +954,14 @@ def getKindleInfoFiles():
if path == "":
print ('Could not find the folder in which to look for kinfoFiles.')
else:
- print('searching for kinfoFiles in ' + path)
+ # Probably not the best. To Fix (shouldn't ignore in encoding) or use utf-8
+ print(u'searching for kinfoFiles in ' + path.encode('ascii', 'ignore'))
# look for (K4PC 1.9.0 and later) .kinf2011 file
kinfopath = path +'\\Amazon\\Kindle\\storage\\.kinf2011'
if os.path.isfile(kinfopath):
found = True
- print('Found K4PC 1.9+ kinf2011 file: ' + kinfopath)
+ print('Found K4PC 1.9+ kinf2011 file: ' + kinfopath.encode('ascii','ignore'))
kInfoFiles.append(kinfopath)
# look for (K4PC 1.6.0 and later) rainier.2.1.1.kinf file
@@ -1142,7 +1160,7 @@ def getDBfromFile(kInfoFile):
cleartext = CryptUnprotectData(encryptedValue, entropy, 1)
DB[keyname] = cleartext
- if 'MazamaRandomNumber' in DB and 'kindle.account.tokens' in DB:
+ if 'kindle.account.tokens' in DB:
print u"Decrypted key file using IDString '{0:s}' and UserName '{1:s}'".format(GetIDString(), GetUserName().decode("latin-1"))
# store values used in decryption
DB['IDString'] = GetIDString()
@@ -1758,7 +1776,7 @@ def getDBfromFile(kInfoFile):
break
except:
pass
- if 'MazamaRandomNumber' in DB and 'kindle.account.tokens' in DB:
+ if 'kindle.account.tokens' in DB:
# store values used in decryption
print u"Decrypted key file using IDString '{0:s}' and UserName '{1:s}'".format(IDString, GetUserName())
DB['IDString'] = IDString
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/kindlepid.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/kindlepid.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/libalfcrypto.dylib b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/libalfcrypto.dylib
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/libalfcrypto32.so b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/libalfcrypto32.so
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/libalfcrypto64.so b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/libalfcrypto64.so
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/mobidedrm.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/mobidedrm.py
old mode 100644
new mode 100755
index 7b69edc..89cc695
--- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/mobidedrm.py
+++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/mobidedrm.py
@@ -156,6 +156,8 @@ def PC1(key, src, decryption=True):
return Pukall_Cipher().PC1(key,src,decryption)
except NameError:
pass
+ except TypeError:
+ pass
# use slow python version, since Pukall_Cipher didn't load
sum1 = 0;
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/openssl_des.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/openssl_des.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/prefs.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/prefs.py
index 2c8c665..05065ac 100755
--- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/prefs.py
+++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/prefs.py
@@ -114,7 +114,7 @@ def parseeReaderString(keystuff):
# Generate eReader user key from name and credit card number.
keyname = u"{0}_{1}".format(name.strip(),cc.strip()[-4:])
keyvalue = getuser_key(name,cc).encode('hex')
- userkeysappend([keyname,keyvalue])
+ userkeys.append([keyname,keyvalue])
except Exception, e:
traceback.print_exc()
print e.args[0]
@@ -231,21 +231,20 @@ def getConfigFiles(extension, encoding = None):
dedrmprefs.addnamedvaluetoprefs('bandnkeys', name, value)
addedkeycount = len(dedrmprefs['bandnkeys'])-priorkeycount
if addedkeycount > 0:
- print u"{0} v{1}: {2:d} Barnes and Noble {3} imported from config folder.".format(PLUGIN_NAME, PLUGIN_VERSION, ignoblecount, u"key file" if ignoblecount==1 else u"key files")
+ print u"{0} v{1}: {2:d} Barnes and Noble {3} imported from config folder.".format(PLUGIN_NAME, PLUGIN_VERSION, addedkeycount, u"key file" if addedkeycount==1 else u"key files")
# Make the json write all the prefs to disk
dedrmprefs.writeprefs(False)
# get any .der files in the config dir
priorkeycount = len(dedrmprefs['adeptkeys'])
adeptfilekeys = getConfigFiles('.der','hex')
- ineptcount = addConfigFiles('.der', 'adeptkeys')
for keypair in adeptfilekeys:
name = keypair[0]
value = keypair[1]
dedrmprefs.addnamedvaluetoprefs('adeptkeys', name, value)
addedkeycount = len(dedrmprefs['adeptkeys'])-priorkeycount
if addedkeycount > 0:
- print u"{0} v{1}: {2:d} Adobe Adept {3} imported from config folder.".format(PLUGIN_NAME, PLUGIN_VERSION, ineptcount, u"keyfile" if ineptcount==1 else u"keyfiles")
+ print u"{0} v{1}: {2:d} Adobe Adept {3} imported from config folder.".format(PLUGIN_NAME, PLUGIN_VERSION, addedkeycount, u"keyfile" if addedkeycount==1 else u"keyfiles")
# Make the json write all the prefs to disk
dedrmprefs.writeprefs(False)
@@ -280,7 +279,7 @@ def getConfigFiles(extension, encoding = None):
if addedserialcount > 0:
print u"{0} v{1}: {2:d} {3} imported from Kindle plugin preferences".format(PLUGIN_NAME, PLUGIN_VERSION, addedserialcount, u"serial number" if addedserialcount==1 else u"serial numbers")
try:
- if kindleprefs['wineprefix'] != "":
+ if 'wineprefix' in kindleprefs and kindleprefs['wineprefix'] != "":
dedrmprefs.set('adobewineprefix',kindleprefs['wineprefix'])
dedrmprefs.set('kindlewineprefix',kindleprefs['wineprefix'])
print u"{0} v{1}: WINEPREFIX ‘(2)’ imported from Kindle plugin preferences".format(PLUGIN_NAME, PLUGIN_VERSION, kindleprefs['wineprefix'])
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/pycrypto_des.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/pycrypto_des.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/python_des.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/python_des.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/scriptinterface.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/scriptinterface.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/scrolltextwidget.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/scrolltextwidget.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/simpleprefs.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/simpleprefs.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/stylexml2css.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/stylexml2css.py
old mode 100644
new mode 100755
index c111850..daa108a
--- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/stylexml2css.py
+++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/stylexml2css.py
@@ -178,7 +178,12 @@ def process(self):
if val == "":
val = 0
- if not ((attr == 'hang') and (int(val) == 0)) :
+ if not ((attr == 'hang') and (int(val) == 0)):
+ try:
+ f = float(val)
+ except:
+ print "Warning: unrecognised val, ignoring"
+ val = 0
pv = float(val)/scale
cssargs[attr] = (self.attr_val_map[attr], pv)
keep = True
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/topazextract.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/topazextract.py
old mode 100644
new mode 100755
index 97f6583..fb5eb7a
--- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/topazextract.py
+++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/topazextract.py
@@ -356,7 +356,7 @@ def processBook(self, pidlst):
self.setBookKey(bookKey)
self.createBookDirectory()
- self.extractFiles()
+ self.extractFiles()
print u"Successfully Extracted Topaz contents"
if inCalibre:
from calibre_plugins.dedrm import genbook
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/utilities.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/utilities.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/wineutils.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/wineutils.py
index f8d5f7a..b54db80 100755
--- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/wineutils.py
+++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/wineutils.py
@@ -24,7 +24,7 @@ def WineGetKeys(scriptpath, extension, wineprefix=""):
outdirpath = os.path.join(basepath, u"winekeysdir")
if not os.path.exists(outdirpath):
- os.mkdir(outdirpath)
+ os.makedirs(outdirpath)
if wineprefix != "" and os.path.exists(wineprefix):
cmdline = u"WINEPREFIX=\"{2}\" wine python.exe \"{0}\" \"{1}\"".format(scriptpath,outdirpath,wineprefix)
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/zipfilerugged.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/zipfilerugged.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/zipfix.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/zipfix.py
old mode 100644
new mode 100755
diff --git a/DeDRM_Windows_Application/DeDRM_App_ReadMe.txt b/DeDRM_Windows_Application/DeDRM_App_ReadMe.txt
old mode 100644
new mode 100755
diff --git a/DeDRM_calibre_plugin/DeDRM_plugin.zip b/DeDRM_calibre_plugin/DeDRM_plugin.zip
old mode 100644
new mode 100755
index 0420378..58d8174
Binary files a/DeDRM_calibre_plugin/DeDRM_plugin.zip and b/DeDRM_calibre_plugin/DeDRM_plugin.zip differ
diff --git a/DeDRM_calibre_plugin/DeDRM_plugin_ReadMe.txt b/DeDRM_calibre_plugin/DeDRM_plugin_ReadMe.txt
old mode 100644
new mode 100755
diff --git a/Other_Tools/B_and_N_Download_Helper/BN-Dload.user_ReadMe.txt b/Other_Tools/B_and_N_Download_Helper/BN-Dload.user_ReadMe.txt
old mode 100644
new mode 100755
diff --git a/Other_Tools/DRM_Key_Scripts/Adobe_Digital_Editions/adobekey.pyw b/Other_Tools/DRM_Key_Scripts/Adobe_Digital_Editions/adobekey.pyw
old mode 100644
new mode 100755
diff --git a/Other_Tools/DRM_Key_Scripts/Barnes_and_Noble_ePubs/ignoblekeygen.pyw b/Other_Tools/DRM_Key_Scripts/Barnes_and_Noble_ePubs/ignoblekeygen.pyw
old mode 100644
new mode 100755
diff --git a/Other_Tools/DRM_Key_Scripts/Kindle_for_Mac_and_PC/kindlekey.pyw b/Other_Tools/DRM_Key_Scripts/Kindle_for_Mac_and_PC/kindlekey.pyw
old mode 100644
new mode 100755
index f58e973..8852769
--- a/Other_Tools/DRM_Key_Scripts/Kindle_for_Mac_and_PC/kindlekey.pyw
+++ b/Other_Tools/DRM_Key_Scripts/Kindle_for_Mac_and_PC/kindlekey.pyw
@@ -19,6 +19,7 @@ from __future__ import with_statement
# 1.6 - Fixed a problem getting the disk serial numbers
# 1.7 - Work if TkInter is missing
# 1.8 - Fixes for Kindle for Mac, and non-ascii in Windows user names
+# 1.9 - Fixes for Unicode in Windows user names
"""
@@ -26,7 +27,7 @@ Retrieve Kindle for PC/Mac user key.
"""
__license__ = 'GPL v3'
-__version__ = '1.8'
+__version__ = '1.9'
import sys, os, re
from struct import pack, unpack, unpack_from
@@ -907,18 +908,34 @@ if iswindows:
return CryptUnprotectData
CryptUnprotectData = CryptUnprotectData()
+ # Returns Environmental Variables that contain unicode
+ def getEnvironmentVariable(name):
+ import ctypes
+ name = unicode(name) # make sure string argument is unicode
+ n = ctypes.windll.kernel32.GetEnvironmentVariableW(name, None, 0)
+ if n == 0:
+ return None
+ buf = ctypes.create_unicode_buffer(u'\0'*n)
+ ctypes.windll.kernel32.GetEnvironmentVariableW(name, buf, n)
+ return buf.value
# Locate all of the kindle-info style files and return as list
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
+ # or the python interface to the 32 vs 64 bit registry is broken
path = ""
if 'LOCALAPPDATA' in os.environ.keys():
- path = os.environ['LOCALAPPDATA']
+ # Python 2.x does not return unicode env. Use Python 3.x
+ path = winreg.ExpandEnvironmentStrings(u"%LOCALAPPDATA%")
+ # this is just another alternative.
+ # path = getEnvironmentVariable('LOCALAPPDATA')
+ if not os.path.isdir(path):
+ path = ""
else:
# User Shell Folders show take precedent over Shell Folders if present
try:
+ # this will still break
regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\")
path = winreg.QueryValueEx(regkey, 'Local AppData')[0]
if not os.path.isdir(path):
@@ -937,13 +954,14 @@ if iswindows:
if path == "":
print ('Could not find the folder in which to look for kinfoFiles.')
else:
- print('searching for kinfoFiles in ' + path)
+ # Probably not the best. To Fix (shouldn't ignore in encoding) or use utf-8
+ print(u'searching for kinfoFiles in ' + path.encode('ascii', 'ignore'))
# look for (K4PC 1.9.0 and later) .kinf2011 file
kinfopath = path +'\\Amazon\\Kindle\\storage\\.kinf2011'
if os.path.isfile(kinfopath):
found = True
- print('Found K4PC 1.9+ kinf2011 file: ' + kinfopath)
+ print('Found K4PC 1.9+ kinf2011 file: ' + kinfopath.encode('ascii','ignore'))
kInfoFiles.append(kinfopath)
# look for (K4PC 1.6.0 and later) rainier.2.1.1.kinf file
@@ -1142,7 +1160,7 @@ if iswindows:
cleartext = CryptUnprotectData(encryptedValue, entropy, 1)
DB[keyname] = cleartext
- if 'MazamaRandomNumber' in DB and 'kindle.account.tokens' in DB:
+ if 'kindle.account.tokens' in DB:
print u"Decrypted key file using IDString '{0:s}' and UserName '{1:s}'".format(GetIDString(), GetUserName().decode("latin-1"))
# store values used in decryption
DB['IDString'] = GetIDString()
@@ -1758,7 +1776,7 @@ elif isosx:
break
except:
pass
- if 'MazamaRandomNumber' in DB and 'kindle.account.tokens' in DB:
+ if 'kindle.account.tokens' in DB:
# store values used in decryption
print u"Decrypted key file using IDString '{0:s}' and UserName '{1:s}'".format(IDString, GetUserName())
DB['IDString'] = IDString
diff --git a/Other_Tools/DRM_Key_Scripts/Kindle_for_iOS/kindleiospidgen.py b/Other_Tools/DRM_Key_Scripts/Kindle_for_iOS/kindleiospidgen.py
new file mode 100755
index 0000000..0c0b11b
--- /dev/null
+++ b/Other_Tools/DRM_Key_Scripts/Kindle_for_iOS/kindleiospidgen.py
@@ -0,0 +1,275 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from __future__ import with_statement
+
+# kindleforios4key.py
+# Copyright © 2013 by Apprentice Alf
+# Portions Copyright © 2007, 2009 Igor Skochinsky
+
+# Revision history:
+# 1.0 - Generates fixed PID for Kindle for iOS 3.1.1 running on iOS 4.x
+
+
+"""
+Generate fixed PID for Kindle for iOS 3.1.1
+"""
+
+__license__ = 'GPL v3'
+__version__ = '1.0'
+
+import sys, os
+import getopt
+import binascii
+
+# Wrap a stream so that output gets flushed immediately
+# and also make sure that any unicode strings get
+# encoded using "replace" before writing them.
+class SafeUnbuffered:
+ def __init__(self, stream):
+ self.stream = stream
+ self.encoding = stream.encoding
+ if self.encoding == None:
+ self.encoding = "utf-8"
+ def write(self, data):
+ if isinstance(data,unicode):
+ data = data.encode(self.encoding,"replace")
+ self.stream.write(data)
+ self.stream.flush()
+ def __getattr__(self, attr):
+ return getattr(self.stream, attr)
+
+iswindows = sys.platform.startswith('win')
+isosx = sys.platform.startswith('darwin')
+
+def unicode_argv():
+ if iswindows:
+ # Uses shell32.GetCommandLineArgvW to get sys.argv as a list of Unicode
+ # strings.
+
+ # Versions 2.x of Python don't support Unicode in sys.argv on
+ # Windows, with the underlying Windows API instead replacing multi-byte
+ # characters with '?'.
+
+
+ from ctypes import POINTER, byref, cdll, c_int, windll
+ from ctypes.wintypes import LPCWSTR, LPWSTR
+
+ GetCommandLineW = cdll.kernel32.GetCommandLineW
+ GetCommandLineW.argtypes = []
+ GetCommandLineW.restype = LPCWSTR
+
+ CommandLineToArgvW = windll.shell32.CommandLineToArgvW
+ CommandLineToArgvW.argtypes = [LPCWSTR, POINTER(c_int)]
+ CommandLineToArgvW.restype = POINTER(LPWSTR)
+
+ cmd = GetCommandLineW()
+ argc = c_int(0)
+ argv = CommandLineToArgvW(cmd, byref(argc))
+ if argc.value > 0:
+ # Remove Python executable and commands if present
+ start = argc.value - len(sys.argv)
+ return [argv[i] for i in
+ xrange(start, argc.value)]
+ # if we don't have any arguments at all, just pass back script name
+ # this should never happen
+ return [u"mobidedrm.py"]
+ else:
+ argvencoding = sys.stdin.encoding
+ if argvencoding == None:
+ argvencoding = "utf-8"
+ return [arg if (type(arg) == unicode) else unicode(arg,argvencoding) for arg in sys.argv]
+
+import hashlib
+
+def SHA256(message):
+ ctx = hashlib.sha256()
+ ctx.update(message)
+ return ctx.digest()
+
+def crc32(s):
+ return (~binascii.crc32(s,-1))&0xFFFFFFFF
+
+letters = 'ABCDEFGHIJKLMNPQRSTUVWXYZ123456789'
+
+def checksumPid(s):
+ crc = crc32(s)
+ crc = crc ^ (crc >> 16)
+ res = s
+ l = len(letters)
+ for i in (0,1):
+ b = crc & 0xff
+ pos = (b // l) ^ (b % l)
+ res += letters[pos%l]
+ crc >>= 8
+
+ return res
+
+def pidFromSerial(s, l):
+ crc = crc32(s)
+
+ arr1 = [0]*l
+ for i in xrange(len(s)):
+ arr1[i%l] ^= ord(s[i])
+
+ crc_bytes = [crc >> 24 & 0xff, crc >> 16 & 0xff, crc >> 8 & 0xff, crc & 0xff]
+ for i in xrange(l):
+ arr1[i] ^= crc_bytes[i&3]
+
+ pid = ''
+ for i in xrange(l):
+ b = arr1[i] & 0xff
+ pid+=letters[(b >> 7) + ((b >> 5 & 3) ^ (b & 0x1f))]
+
+ return pid
+
+def generatekeys(email, mac):
+ keys = []
+ email = email.encode('utf-8').lower()
+ mac = mac.encode('utf-8').lower()
+ cleanmac = "".join(c if (c in "0123456789abcdef") else "" for c in mac)
+ lowermac = cleanmac.lower()
+ #print lowermac
+ keyseed = lowermac + email.encode('utf-8')
+ #print keyseed
+ keysha256 = SHA256(keyseed)
+ keybase64 = keysha256.encode('base64')
+ #print keybase64
+ cleankeybase64 = "".join(c if (c in "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") else "0" for c in keybase64)
+ #print cleankeybase64
+ pseudoudid = cleankeybase64[:40]
+ #print pseudoudid
+ keys.append(pidFromSerial(pseudoudid.encode("utf-8"),8))
+ return keys
+
+# interface for Python DeDRM
+# returns single key or multiple keys, depending on path or file passed in
+def getkey(email, mac, outpath):
+ keys = generatekeys(email,mac)
+ if len(keys) > 0:
+ if not os.path.isdir(outpath):
+ outfile = outpath
+ with file(outfile, 'w') as keyfileout:
+ keyfileout.write(keys[0])
+ print u"Saved a key to {0}".format(outfile)
+ else:
+ keycount = 0
+ for key in keys:
+ while True:
+ keycount += 1
+ outfile = os.path.join(outpath,u"kindleios{0:d}.pid".format(keycount))
+ if not os.path.exists(outfile):
+ break
+ with file(outfile, 'w') as keyfileout:
+ keyfileout.write(key)
+ print u"Saved a key to {0}".format(outfile)
+ return True
+ return False
+
+def usage(progname):
+ print u"Generates the key for Kindle for iOS 3.1.1"
+ print u"Requires email address of Amazon acccount"
+ print u"And MAC address for iOS device’s wifi"
+ print u"Outputs to a file or to stdout"
+ print u"Usage:"
+ print u" {0:s} [-h] []".format(progname)
+
+
+def cli_main():
+ sys.stdout=SafeUnbuffered(sys.stdout)
+ sys.stderr=SafeUnbuffered(sys.stderr)
+ argv=unicode_argv()
+ progname = os.path.basename(argv[0])
+ print u"{0} v{1}\nCopyright © 2013 Apprentice Alf".format(progname,__version__)
+
+ try:
+ opts, args = getopt.getopt(argv[1:], "h")
+ except getopt.GetoptError, err:
+ print u"Error in options or arguments: {0}".format(err.args[0])
+ usage(progname)
+ sys.exit(2)
+
+ for o, a in opts:
+ if o == "-h":
+ usage(progname)
+ sys.exit(0)
+
+
+ if len(args) < 2 or len(args) > 3:
+ usage(progname)
+ sys.exit(2)
+
+ if len(args) == 3:
+ # save to the specified file or folder
+ getkey(args[0],args[1],args[2])
+ else:
+ keys = generatekeys(args[0],args[1])
+ for key in keys:
+ print key
+
+ return 0
+
+
+def gui_main():
+ try:
+ import Tkinter
+ import Tkconstants
+ import tkMessageBox
+ except:
+ print "Tkinter not installed"
+ return cli_main()
+
+ class DecryptionDialog(Tkinter.Frame):
+ def __init__(self, root):
+ Tkinter.Frame.__init__(self, root, border=5)
+ self.status = Tkinter.Label(self, text=u"Enter parameters")
+ self.status.pack(fill=Tkconstants.X, expand=1)
+ body = Tkinter.Frame(self)
+ body.pack(fill=Tkconstants.X, expand=1)
+ sticky = Tkconstants.E + Tkconstants.W
+ body.grid_columnconfigure(1, weight=2)
+ Tkinter.Label(body, text=u"Amazon email address").grid(row=0)
+ self.email = Tkinter.Entry(body, width=40)
+ self.email.grid(row=0, column=1, sticky=sticky)
+ Tkinter.Label(body, text=u"iOS MAC address").grid(row=1)
+ self.mac = Tkinter.Entry(body, width=40)
+ self.mac.grid(row=1, column=1, sticky=sticky)
+ buttons = Tkinter.Frame(self)
+ buttons.pack()
+ button = Tkinter.Button(
+ buttons, text=u"Generate", width=10, command=self.generate)
+ button.pack(side=Tkconstants.LEFT)
+ Tkinter.Frame(buttons, width=10).pack(side=Tkconstants.LEFT)
+ button = Tkinter.Button(
+ buttons, text=u"Quit", width=10, command=self.quit)
+ button.pack(side=Tkconstants.RIGHT)
+
+ def generate(self):
+ email = self.email.get()
+ mac = self.mac.get()
+ if not email:
+ self.status['text'] = u"Email not specified"
+ return
+ if not mac:
+ self.status['text'] = u"MAC not specified"
+ return
+ self.status['text'] = u"Generating..."
+ try:
+ keys = generatekeys(email, mac)
+ except Exception, e:
+ self.status['text'] = u"Error: (0}".format(e.args[0])
+ return
+ self.status['text'] = ", ".join(key for key in keys)
+
+ root = Tkinter.Tk()
+ root.title(u"Kindle for iOS PID Generator v.{0}".format(__version__))
+ root.resizable(True, False)
+ root.minsize(300, 0)
+ DecryptionDialog(root).pack(fill=Tkconstants.X, expand=1)
+ root.mainloop()
+ return 0
+
+if __name__ == '__main__':
+ if len(sys.argv) > 1:
+ sys.exit(cli_main())
+ sys.exit(gui_main())
diff --git a/Other_Tools/Kindle_for_Android_Patches/A_Patching_Experience.txt b/Other_Tools/Kindle_for_Android_Patches/A_Patching_Experience.txt
old mode 100644
new mode 100755
diff --git a/Other_Tools/Kindle_for_Android_Patches/kindle_version_3.0.1.70/ReadMe_K4Android.txt b/Other_Tools/Kindle_for_Android_Patches/kindle_version_3.0.1.70/ReadMe_K4Android.txt
old mode 100644
new mode 100755
diff --git a/Other_Tools/Kindle_for_Android_Patches/kindle_version_3.0.1.70/kindle3.0.1.70.patch b/Other_Tools/Kindle_for_Android_Patches/kindle_version_3.0.1.70/kindle3.0.1.70.patch
old mode 100644
new mode 100755
diff --git a/Other_Tools/Kindle_for_Android_Patches/kindle_version_3.7.0.108/ReadMe_K4Android.txt b/Other_Tools/Kindle_for_Android_Patches/kindle_version_3.7.0.108/ReadMe_K4Android.txt
old mode 100644
new mode 100755
diff --git a/Other_Tools/Kindle_for_Android_Patches/kindle_version_3.7.0.108/kindle3.7.0.108.patch b/Other_Tools/Kindle_for_Android_Patches/kindle_version_3.7.0.108/kindle3.7.0.108.patch
old mode 100644
new mode 100755
diff --git a/Other_Tools/Kindle_for_Android_Patches/kindle_version_4.0.2.1/kindle4.0.2.1.patch b/Other_Tools/Kindle_for_Android_Patches/kindle_version_4.0.2.1/kindle4.0.2.1.patch
old mode 100644
new mode 100755
diff --git a/Other_Tools/Kindle_for_Android_Patches/kindle_version_4.3.0.67/Changelog b/Other_Tools/Kindle_for_Android_Patches/kindle_version_4.3.0.67/Changelog
deleted file mode 100644
index 5c903c2..0000000
--- a/Other_Tools/Kindle_for_Android_Patches/kindle_version_4.3.0.67/Changelog
+++ /dev/null
@@ -1,3 +0,0 @@
-changes from 4.0.2.1 to 4.3.0.67:
-- minor adjustment in smali/com/amazon/kcp/application/AndroidDeviceInformationProvider.smali
- to make the patch apply cleanly
diff --git a/Other_Tools/Kindle_for_Android_Patches/kindle_version_4.3.0.67/kindle4.3.0.67.patch b/Other_Tools/Kindle_for_Android_Patches/kindle_version_4.3.0.67/kindle4.3.0.67.patch
deleted file mode 100644
index 01a8cc8..0000000
--- a/Other_Tools/Kindle_for_Android_Patches/kindle_version_4.3.0.67/kindle4.3.0.67.patch
+++ /dev/null
@@ -1,153 +0,0 @@
-diff -ru '--exclude=.git' kindle4.3.0.67_orig/smali/com/amazon/kcp/application/AndroidDeviceInformationProvider.smali kindle4.3.0.67/smali/com/amazon/kcp/application/AndroidDeviceInformationProvider.smali
---- kindle4.3.0.67_orig/smali/com/amazon/kcp/application/AndroidDeviceInformationProvider.smali 2014-01-13 00:32:44.788420082 +0100
-+++ kindle4.3.0.67/smali/com/amazon/kcp/application/AndroidDeviceInformationProvider.smali 2014-01-11 17:57:20.439183833 +0100
-@@ -43,6 +43,8 @@
-
- .field private security:Lcom/mobipocket/android/library/reader/AndroidSecurity;
-
-+.field private pidList:Ljava/lang/String;
-+
- .field private totalMemory:J
-
-
-@@ -83,6 +85,10 @@
-
- iput-object v0, p0, Lcom/amazon/kcp/application/AndroidDeviceInformationProvider;->deviceType:Lcom/amazon/kcp/application/AmazonDeviceType;
-
-+ const-string v0, "Open DRMed book to show PID list."
-+
-+ iput-object v0, p0, Lcom/amazon/kcp/application/AndroidDeviceInformationProvider;->pidList:Ljava/lang/String;
-+
- .line 134
- sget-object v0, Lcom/amazon/kcp/application/AndroidDeviceInformationProvider;->TAG:Ljava/lang/String;
-
-@@ -1348,3 +1354,25 @@
-
- return-wide v0
- .end method
-+
-+.method public getPidList()Ljava/lang/String;
-+ .locals 1
-+
-+ .prologue
-+ .line 15
-+ iget-object v0, p0, Lcom/amazon/kcp/application/AndroidDeviceInformationProvider;->pidList:Ljava/lang/String;
-+
-+ return-object v0
-+.end method
-+
-+.method public setPidList(Ljava/lang/String;)V
-+ .locals 0
-+ .parameter "value"
-+
-+ .prologue
-+ .line 11
-+ iput-object p1, p0, Lcom/amazon/kcp/application/AndroidDeviceInformationProvider;->pidList:Ljava/lang/String;
-+
-+ .line 12
-+ return-void
-+.end method
-Only in kindle4.3.0.67/smali/com/amazon/kcp/application: AndroidDeviceInformationProvider.smali.rej
-diff -ru '--exclude=.git' kindle4.3.0.67_orig/smali/com/amazon/kcp/application/IDeviceInformationProvider.smali kindle4.3.0.67/smali/com/amazon/kcp/application/IDeviceInformationProvider.smali
---- kindle4.3.0.67_orig/smali/com/amazon/kcp/application/IDeviceInformationProvider.smali 2014-01-13 00:32:45.121755742 +0100
-+++ kindle4.3.0.67/smali/com/amazon/kcp/application/IDeviceInformationProvider.smali 2014-01-11 17:54:48.949501717 +0100
-@@ -30,3 +30,9 @@
-
- .method public abstract getPid()Ljava/lang/String;
- .end method
-+
-+.method public abstract getPidList()Ljava/lang/String;
-+.end method
-+
-+.method public abstract setPidList(Ljava/lang/String;)V
-+.end method
-diff -ru '--exclude=.git' kindle4.3.0.67_orig/smali/com/amazon/kcp/info/AboutActivity.smali kindle4.3.0.67/smali/com/amazon/kcp/info/AboutActivity.smali
---- kindle4.3.0.67_orig/smali/com/amazon/kcp/info/AboutActivity.smali 2014-01-13 00:32:46.291763912 +0100
-+++ kindle4.3.0.67/smali/com/amazon/kcp/info/AboutActivity.smali 2014-01-11 17:54:48.949501717 +0100
-@@ -493,6 +493,57 @@
- return-void
- .end method
-
-+.method private populatePIDList()V
-+ .locals 7
-+
-+ .prologue
-+ .line 313
-+ invoke-static {}, Lcom/amazon/kcp/application/DeviceInformationProviderFactory;->getProvider()Lcom/amazon/kcp/application/IDeviceInformationProvider;
-+
-+ move-result-object v0
-+
-+ invoke-interface {v0}, Lcom/amazon/kcp/application/IDeviceInformationProvider;->getPidList()Ljava/lang/String;
-+
-+ move-result-object v1
-+
-+ .line 314
-+ .local v1, PidList:Ljava/lang/String;
-+ iget-object v3, p0, Lcom/amazon/kcp/info/AboutActivity;->groupItemList:Ljava/util/List;
-+
-+ new-instance v4, Lcom/amazon/kcp/info/AboutActivity$GroupItem;
-+
-+ const-string v5, "PID List"
-+
-+ const v6, 0x1
-+
-+ invoke-direct {v4, p0, v5, v6}, Lcom/amazon/kcp/info/AboutActivity$GroupItem;->(Lcom/amazon/kcp/info/AboutActivity;Ljava/lang/String;Z)V
-+
-+ invoke-interface {v3, v4}, Ljava/util/List;->add(Ljava/lang/Object;)Z
-+
-+ .line 315
-+ new-instance v2, Ljava/util/ArrayList;
-+
-+ invoke-direct {v2}, Ljava/util/ArrayList;->()V
-+
-+ .line 316
-+ .local v2, children:Ljava/util/List;,"Ljava/util/List;"
-+ new-instance v3, Lcom/amazon/kcp/info/AboutActivity$DetailItem;
-+
-+ const-string v4, "PIDs"
-+
-+ invoke-direct {v3, p0, v4, v1}, Lcom/amazon/kcp/info/AboutActivity$DetailItem;->(Lcom/amazon/kcp/info/AboutActivity;Ljava/lang/String;Ljava/lang/String;)V
-+
-+ invoke-interface {v2, v3}, Ljava/util/List;->add(Ljava/lang/Object;)Z
-+
-+ .line 317
-+ iget-object v3, p0, Lcom/amazon/kcp/info/AboutActivity;->detailItemList:Ljava/util/List;
-+
-+ invoke-interface {v3, v2}, Ljava/util/List;->add(Ljava/lang/Object;)Z
-+
-+ .line 318
-+ return-void
-+.end method
-+
- .method private populateDisplayItems()V
- .locals 1
-
-@@ -538,6 +589,8 @@
- .line 194
- invoke-direct {p0}, Lcom/amazon/kcp/info/AboutActivity;->populateDisplayInformation()V
-
-+ invoke-direct {p0}, Lcom/amazon/kcp/info/AboutActivity;->populatePIDList()V
-+
- .line 195
- return-void
-
-diff -ru '--exclude=.git' kindle4.3.0.67_orig/smali/com/amazon/system/security/Security.smali kindle4.3.0.67/smali/com/amazon/system/security/Security.smali
---- kindle4.3.0.67_orig/smali/com/amazon/system/security/Security.smali 2014-01-13 00:32:59.355188695 +0100
-+++ kindle4.3.0.67/smali/com/amazon/system/security/Security.smali 2014-01-11 17:54:48.949501717 +0100
-@@ -942,6 +942,16 @@
-
- aput-object v0, v6, v8
-
-+ invoke-static {}, Lcom/amazon/kcp/application/DeviceInformationProviderFactory;->getProvider()Lcom/amazon/kcp/application/IDeviceInformationProvider;
-+
-+ move-result-object v5
-+
-+ invoke-static {v6}, Ljava/util/Arrays;->toString([Ljava/lang/Object;)Ljava/lang/String;
-+
-+ move-result-object v2
-+
-+ invoke-interface {v5, v2}, Lcom/amazon/kcp/application/IDeviceInformationProvider;->setPidList(Ljava/lang/String;)V
-+
- .line 353
- return-object v6
- .end method
diff --git a/Other_Tools/Kobo/obok_2.01.py b/Other_Tools/Kobo/obok_2.01.py
new file mode 100755
index 0000000..7c61852
--- /dev/null
+++ b/Other_Tools/Kobo/obok_2.01.py
@@ -0,0 +1,231 @@
+#!/usr/bin/env python
+#
+# Updated September 2013 by Anon
+# Version 2.01
+# Incorporated minor fixes posted at Apprentice Alf's.
+#
+# Updates July 2012 by Michael Newton
+# PWSD ID is no longer a MAC address, but should always
+# be stored in the registry. Script now works with OS X
+# and checks plist for values instead of registry. Must
+# have biplist installed for OS X support.
+#
+##########################################################
+# KOBO DRM CRACK BY #
+# PHYSISTICATED #
+##########################################################
+# This app was made for Python 2.7 on Windows 32-bit
+#
+# This app needs pycrypto - get from here:
+# http://www.voidspace.org.uk/python/modules.shtml
+#
+# Usage: obok.py
+# Choose the book you want to decrypt
+#
+# Shouts to my krew - you know who you are - and one in
+# particular who gave me a lot of help with this - thank
+# you so much!
+#
+# Kopimi /K\
+# Keep sharing, keep copying, but remember that nothing is
+# for free - make sure you compensate your favorite
+# authors - and cut out the middle man whenever possible
+# ;) ;) ;)
+#
+# DRM AUTOPSY
+# The Kobo DRM was incredibly easy to crack, but it took
+# me months to get around to making this. Here's the
+# basics of how it works:
+# 1: Get MAC address of first NIC in ipconfig (sometimes
+# stored in registry as pwsdid)
+# 2: Get user ID (stored in tons of places, this gets it
+# from HKEY_CURRENT_USER\Software\Kobo\Kobo Desktop
+# Edition\Browser\cookies)
+# 3: Concatenate and SHA256, take the second half - this
+# is your master key
+# 4: Open %LOCALAPPDATA%\Kobo Desktop Editions\Kobo.sqlite
+# and dump content_keys
+# 5: Unbase64 the keys, then decode these with the master
+# key - these are your page keys
+# 6: Unzip EPUB of your choice, decrypt each page with its
+# page key, then zip back up again
+#
+# WHY USE THIS WHEN INEPT WORKS FINE? (adobe DRM stripper)
+# Inept works very well, but authors on Kobo can choose
+# what DRM they want to use - and some have chosen not to
+# let people download them with Adobe Digital Editions -
+# they would rather lock you into a single platform.
+#
+# With Obok, you can sync Kobo Desktop, decrypt all your
+# ebooks, and then use them on whatever device you want
+# - you bought them, you own them, you can do what you
+# like with them.
+#
+# Obok is Kobo backwards, but it is also means "next to"
+# in Polish.
+# When you buy a real book, it is right next to you. You
+# can read it at home, at work, on a train, you can lend
+# it to a friend, you can scribble on it, and add your own
+# explanations/translations.
+#
+# Obok gives you this power over your ebooks - no longer
+# are you restricted to one device. This allows you to
+# embed foreign fonts into your books, as older Kobo's
+# can't display them properly. You can read your books
+# on your phones, in different PC readers, and different
+# ereader devices. You can share them with your friends
+# too, if you like - you can do that with a real book
+# after all.
+#
+"""
+Decrypt Kobo encrypted EPUB books.
+"""
+
+import os
+import sys
+if sys.platform.startswith('win'):
+ import _winreg
+elif sys.platform.startswith('darwin'):
+ from biplist import readPlist
+import re
+import string
+import hashlib
+import sqlite3
+import base64
+import binascii
+import zipfile
+from Crypto.Cipher import AES
+
+def SHA256(raw):
+ return hashlib.sha256(raw).hexdigest()
+
+def RemoveAESPadding(contents):
+ lastchar = binascii.b2a_hex(contents[-1:])
+ strlen = int(lastchar, 16)
+ padding = strlen
+ if(strlen == 1):
+ return contents[:-1]
+ if(strlen < 16):
+ for i in range(strlen):
+ testchar = binascii.b2a_hex(contents[-strlen:-(strlen-1)])
+ if(testchar != lastchar):
+ padding = 0
+ if(padding > 0):
+ contents = contents[:-padding]
+ return contents
+
+def GetVolumeKeys(dbase, enc):
+ volumekeys = {}
+ for row in dbase.execute("SELECT * from content_keys"):
+ if(row[0] not in volumekeys):
+ volumekeys[row[0]] = {}
+ volumekeys[row[0]][row[1]] = {}
+ volumekeys[row[0]][row[1]]["encryptedkey"] = base64.b64decode(row[2])
+ volumekeys[row[0]][row[1]]["decryptedkey"] = enc.decrypt(volumekeys[row[0]][row[1]]["encryptedkey"])
+ # get book name
+ for key in volumekeys.keys():
+ volumekeys[key]["title"] = dbase.execute("SELECT Title from content where ContentID = '%s'" % (key)).fetchone()[0]
+ return volumekeys
+
+def ByteArrayToString(bytearr):
+ wincheck = re.match("@ByteArray\\((.+)\\)", bytearr)
+ if wincheck:
+ return wincheck.group(1)
+ return bytearr
+
+def GetUserHexKey(prefs = ""):
+ "find wsuid and pwsdid"
+ wsuid = ""
+ pwsdid = ""
+ if sys.platform.startswith('win'):
+ regkey_browser = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, "Software\\Kobo\\Kobo Desktop Edition\\Browser")
+ cookies = _winreg.QueryValueEx(regkey_browser, "cookies")
+ bytearrays = cookies[0]
+ elif sys.platform.startswith('darwin'):
+ cookies = readPlist(prefs)
+ bytearrays = cookies["Browser.cookies"]
+ for bytearr in bytearrays:
+ cookie = ByteArrayToString(bytearr)
+ print cookie
+ wsuidcheck = re.match("^wsuid=([0-9a-f-]+)", cookie)
+ if(wsuidcheck):
+ wsuid = wsuidcheck.group(1)
+ pwsdidcheck = re.match("^pwsdid=([0-9a-f-]+)", cookie)
+ if (pwsdidcheck):
+ pwsdid = pwsdidcheck.group(1)
+
+ if(wsuid == "" or pwsdid == ""):
+ print "wsuid or pwsdid key not found :/"
+ exit()
+ preuserkey = string.join((pwsdid, wsuid), "")
+ print SHA256(pwsdid)
+ userkey = SHA256(preuserkey)
+ return userkey[32:]
+
+# get dirs
+if sys.platform.startswith('win'):
+ delim = "\\"
+ if (sys.getwindowsversion().major > 5):
+ kobodir = string.join((os.environ['LOCALAPPDATA'], "Kobo\\Kobo Desktop Edition"), delim)
+ else:
+ kobodir = string.join((os.environ['USERPROFILE'], "Local Settings\\Application Data\\Kobo\\Kobo Desktop Edition"), delim)
+ prefs = ""
+elif sys.platform.startswith('darwin'):
+ delim = "/"
+ kobodir = string.join((os.environ['HOME'], "Library/Application Support/Kobo/Kobo Desktop Edition"), delim)
+ prefs = string.join((os.environ['HOME'], "Library/Preferences/com.kobo.Kobo Desktop Edition.plist"), delim)
+sqlitefile = string.join((kobodir, "Kobo.sqlite"), delim)
+bookdir = string.join((kobodir, "kepub"), delim)
+
+# get key
+userkeyhex = GetUserHexKey(prefs)
+# load into AES
+userkey = binascii.a2b_hex(userkeyhex)
+enc = AES.new(userkey, AES.MODE_ECB)
+
+# open sqlite
+conn = sqlite3.connect(sqlitefile)
+dbcursor = conn.cursor()
+# get volume keys
+volumekeys = GetVolumeKeys(dbcursor, enc)
+
+# choose a volumeID
+
+volumeid = ""
+print "Choose a book to decrypt:"
+i = 1
+for key in volumekeys.keys():
+ print "%d: %s" % (i, volumekeys[key]["title"])
+ i += 1
+
+num = input("...")
+
+i = 1
+for key in volumekeys.keys():
+ if(i == num):
+ volumeid = key
+ i += 1
+
+if(volumeid == ""):
+ exit()
+
+zippath = string.join((bookdir, volumeid), delim)
+
+z = zipfile.ZipFile(zippath, "r")
+# make filename out of Unicode alphanumeric and whitespace equivalents from title
+outname = "%s.epub" % (re.sub("[^\s\w]", "", volumekeys[volumeid]["title"], 0, re.UNICODE))
+zout = zipfile.ZipFile(outname, "w", zipfile.ZIP_DEFLATED)
+for filename in z.namelist():
+ #print filename
+ # read in and decrypt
+ if(filename in volumekeys[volumeid]):
+ # do decrypted version
+ pagekey = volumekeys[volumeid][filename]["decryptedkey"]
+ penc = AES.new(pagekey, AES.MODE_ECB)
+ contents = RemoveAESPadding(penc.decrypt(z.read(filename)))
+ # need to fix padding
+ zout.writestr(filename, contents)
+ else:
+ zout.writestr(filename, z.read(filename))
+
+print "Book saved as %s%s%s" % (os.getcwd(), delim, outname)
\ No newline at end of file
diff --git a/Other_Tools/Rocket_ebooks/rebhack.zip b/Other_Tools/Rocket_ebooks/rebhack.zip
old mode 100644
new mode 100755
diff --git a/Other_Tools/Scuolabook_DRM/Scuolabook_DRM_Remover_1.0.zip b/Other_Tools/Scuolabook_DRM/Scuolabook_DRM_Remover_1.0.zip
old mode 100644
new mode 100755
diff --git a/Other_Tools/Scuolabook_DRM/Scuolabook_DRM_Remover_source_19_11_2012.zip b/Other_Tools/Scuolabook_DRM/Scuolabook_DRM_Remover_source_19_11_2012.zip
old mode 100644
new mode 100755
diff --git a/readme.md b/readme.md
index 2fa1065..8997b2b 100644
--- a/readme.md
+++ b/readme.md
@@ -1,10 +1,23 @@
-# DRM Removal Tools for eBooks v6.0.4
+# DRM Removal Tools for eBooks v6.0.8
This repository is a copy of the tools downloaded from [Apprentice Alf's Blog](http://www.apprenticealf.wordpress.com). I am not the author of these tools. I just wanted to keep them in a safe place. More info is at Apprentice Alf's blog post ["DRM Removal Tools for eBooks"](http://apprenticealf.wordpress.com/2012/09/10/drm-removal-tools-for-ebooks/).
# Notes
- I've changed the ReadMe_First.txt to readme.md
- Updated the readme.md with change notes and also citing the original author of the tools
+## Changes in 6.0.8:
+- Fixes invalid topaz files
+
+## Changes in 6.0.7:
+- Fixes wine key creation folder issue.
+- Fixes DeDRM of PDFs with broken metadata.
+
+## Changes in 6.0.6:
+- Fixed up an incorrect function call. (Only relevant for Linux users using Wine)
+
+## Changes in 6.0.5:
+- Fixed a problem that resulted in key issues (thanks, Paul)
+
## Changes in 6.0.4:
- Fixed a problem in the plugin converting earlier preferences (thanks, enno)
- Fixed a problem in the plugin with importing pdb files (thanks, Tina Bird)
@@ -23,7 +36,7 @@ This repository is a copy of the tools downloaded from [Apprentice Alf's Blog](h
Welcome to the tools!
=====================
-This readme.md is meant to give users a quick overview of what is available and how to get started. This document is part of the Tools v6.0.4 archive from Apprentice Alf's Blog: http://apprenticealf.wordpress.com/
+This readme.md is meant to give users a quick overview of what is available and how to get started. This document is part of the Tools v6.0.5 archive from Apprentice Alf's Blog: http://apprenticealf.wordpress.com/
The is archive includes tools to remove DRM from:
@@ -39,55 +52,55 @@ These tools do NOT work with Apple's iBooks FairPlay DRM (see end of this file.)
About the tools
---------------
-These tools have been updated and maintained by Apprentice Alf, DiapDealer and some_updates. You can find the latest updates and get support at Apprentice Alf's blog: http://www.apprenticealf.wordpress.com/
+These tools have been updated and maintained by Apprentice Alf, DiapDealer and some_updates. You can find the latest updates and get support at Apprentice Alf's blog: http://www.apprenticealf.wordpress.com/
If you re-post these tools, a link to the blog would be appreciated.
-The original inept and ignoble scripts were by i♥cabbages
-The original mobidedrm and erdr2pml scripts were by The Dark Reverser
-The original topaz DRM removal script was by CMBDTC
-The original topaz format conversion scripts were by some_updates, clarknova and Bart Simpson
-The Scuolabooks tool is by Hex
-The calibre plugin conversions were originally by DiapDealer
+The original inept and ignoble scripts were by i♥cabbages
+The original mobidedrm and erdr2pml scripts were by The Dark Reverser
+The original topaz DRM removal script was by CMBDTC
+The original topaz format conversion scripts were by some_updates, clarknova and Bart Simpson
+The Scuolabooks tool is by Hex
+The calibre plugin conversions were originally by DiapDealer
-The DeDRM plugin is by Apprentice Alf based on plugins by DiapDealer
-The DeDRM AppleScript application is by Apprentice Alf
-The DeDRM python GUI is by some_updates and Apprentice Alf
+The DeDRM plugin is by Apprentice Alf based on plugins by DiapDealer
+The DeDRM AppleScript application is by Apprentice Alf
+The DeDRM python GUI is by some_updates and Apprentice Alf
Many fixes, updates and enhancements to the scripts and applicatons have been by Apprentice Alf, some_updates and DiapDealer and others.
DeDRM plugin for calibre (Mac OS X, Windows, and Linux)
-------------------------------------------------------
-If you already use calibre, the quickest and easiest way, especially on Windows, to remove DRM from your ebooks is to install the DeDRM plugin from the `DeDRM_calibre_plugin` folder, following the instructions and configuration directions provided in the ReadMe and the help links.
+If you already use calibre, the quickest and easiest way, especially on Windows, to remove DRM from your ebooks is to install the DeDRM plugin from the DeDRM_calibre_plugin folder, following the instructions and configuration directions provided in the ReadMe and the help links.
Once installed and configured, you can simply add a DRM book to calibre and the DeDRMed version will be imported into the calibre database. Note that DRM removal ONLY occurs on import. If you have already imported DRM books you'll need to remove them from calibre and re-import them.
-These plugins work for Windows, Mac OS X and Linux. For ebooks from Kindle 4 PC and Adobe Digital Editions, Linux users should read the section at the end the `DeDRM_plugin_ReadMe.txt` file.
+These plugins work for Windows, Mac OS X and Linux. For ebooks from Kindle 4 PC and Adobe Digital Editions, Linux users should read the section at the end the DeDRM_plugin_ReadMe.txt file.
DeDRM application for Mac OS X users: (Mac OS X 10.4 and above)
---------------------------------------------------------------
This application is a stand-alone application for Mac OS X users.
-Drag the `DeDRM.app` application from the `DeDRM_Macintosh_Application` folder to your Desktop (or your Applications Folder, or anywhere else you find convenient). Double-click on the application to run it and you will be able to enter any configuration data needed to remove DRM from your type of DRMed ebooks.
+Drag the "DeDRM.app" application from the DeDRM_Macintosh_Application folder to your Desktop (or your Applications Folder, or anywhere else you find convenient). Double-click on the application to run it and you will be able to enter any configuration data needed to remove DRM from your type of DRMed ebooks.
To use the DeDRM application simply drag ebooks and/or folders containing ebooks onto the DeDRM application and it will remove the DRM and save DRM-free versions of the books wherever you selected in the Output Folder configuration dialog.
-For more detailed instructions, see the `DeDRM ReadMe.rtf` file in the `DeDRM_Application_Macintosh` folder, including details of the extra step that Mac OS X 10.4 users need to take to use the application.
+For more detailed instructions, see the "DeDRM ReadMe.rtf" file in the DeDRM_Application_Macintosh folder, including details of the extra step that Mac OS X 10.4 users need to take to use the application.
DeDRM application for Windows users: (Windows XP through Windows 8)
------------------------------------------------------------------
-***This program requires that Python and PyCrypto be properly installed.***
+***This program requires that Python and PyCrypto be properly installed.***
***See below for details on recommended versions and how to install them.***
This application is a stand-alone application for Windows users.
-Drag the `DeDRM_App` folder that's in the `DeDRM_Windows_Application` folder, to your `My Documents` folder (or anywhere else you find convenient). Make a short-cut on your Desktop of the `DeDRM_Drop_Target.bat` file that's in the `DeDRM_App` folder. Double-click on the shortcut and the DeDRM application will run and you will be able to enter any configuration data needed to remove DRM from your type of DRMed ebooks.
+Drag the DeDRM_App folder that's in the DeDRM_Windows_Application folder, to your "My Documents" folder (or anywhere else you find convenient). Make a short-cut on your Desktop of the DeDRM_Drop_Target.bat file that's in the DeDRM_App folder. Double-click on the shortcut and the DeDRM application will run and you will be able to enter any configuration data needed to remove DRM from your type of DRMed ebooks.
-To use the DeDRM application simply drag ebooks or folders containing ebooks onto the `DeDRM_Drop_Target.bat` shortcut and it will remove the DRM and save DRM-free versions of the books wherever you selected in the Output Folder configuration dialog.
+To use the DeDRM application simply drag ebooks or folders containing ebooks onto the DeDRM_Drop_Target.bat shortcut and it will remove the DRM and save DRM-free versions of the books wherever you selected in the Output Folder configuration dialog.
-For more detailed instructions, see the `DeDRM_App_ReadMe.txt` file in the `DeDRM_Windows_Applications` folder.
+For more detailed instructions, see the DeDRM_App_ReadMe.txt file in the DeDRM_Windows_Applications folder.
Other_Tools