From e5e269fbae85c59c7faf61fbbf05b610a35aaf67 Mon Sep 17 00:00:00 2001 From: apprenticeharper Date: Thu, 3 Sep 2015 07:51:10 +0100 Subject: [PATCH] Fixes for android key extraction --- .../DeDRM.app/Contents/Info.plist | 4 +-- .../DeDRM.app/Contents/Resources/__init__.py | 5 +-- .../Contents/Resources/androidkindlekey.py | 31 ++++++++++++------ .../DeDRM_App/DeDRM_lib/DeDRM_App.pyw | 3 +- .../DeDRM_App/DeDRM_lib/lib/__init__.py | 5 +-- .../DeDRM_lib/lib/androidkindlekey.py | 31 ++++++++++++------ DeDRM_calibre_plugin/DeDRM_plugin.zip | Bin 353297 -> 353415 bytes DeDRM_calibre_plugin/DeDRM_plugin/__init__.py | 5 +-- .../DeDRM_plugin/androidkindlekey.py | 31 ++++++++++++------ .../Kindle_for_Android/androidkindlekey.pyw | 31 ++++++++++++------ ReadMe_First.txt | 2 +- 11 files changed, 98 insertions(+), 50 deletions(-) diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist index 51d226d..a18d8e4 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist @@ -24,7 +24,7 @@ CFBundleExecutable droplet CFBundleGetInfoString - DeDRM AppleScript 6.3.3 Written 2010–2015 by Apprentice Alf et al. + DeDRM AppleScript 6.3.4 Written 2010–2015 by Apprentice Alf et al. CFBundleIconFile DeDRM CFBundleIdentifier @@ -36,7 +36,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 6.3.3 + 6.3.4 CFBundleSignature dplt LSRequiresCarbon diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py index 1f34cfe..53b1200 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py @@ -45,6 +45,7 @@ __docformat__ = 'restructuredtext en' # 6.3.1 - Version number bump for clarity # 6.3.2 - Fixed Kindle for Android help file # 6.3.3 - Bug fix for Kindle for PC support +# 6.3.4 - Fixes for Kindle for Android, Linux, and Kobo 3.17 """ @@ -52,7 +53,7 @@ Decrypt DRMed ebooks. """ PLUGIN_NAME = u"DeDRM" -PLUGIN_VERSION_TUPLE = (6, 3, 3) +PLUGIN_VERSION_TUPLE = (6, 3, 4) 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' @@ -148,7 +149,7 @@ class DeDRM(FileTypePlugin): try: open(file_path,'wb').write(data) except: - print u"{0} v{1}: Exception when copying needed library files after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime) + print u"{0} v{1}: Exception when copying needed library files".format(PLUGIN_NAME, PLUGIN_VERSION) traceback.print_exc() pass diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/androidkindlekey.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/androidkindlekey.py index 2c539ee..ff8d1ee 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/androidkindlekey.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/androidkindlekey.py @@ -16,16 +16,18 @@ from __future__ import with_statement # - and added in unicode command line support # 1.3 - added in TkInter interface, output to a file # 1.4 - Fix some problems identified by Aldo Bleeker +# 1.5 - Fix another problem identified by Aldo Bleeker """ Retrieve Kindle for Android Serial Number. """ __license__ = 'GPL v3' -__version__ = '1.4' +__version__ = '1.5' import os import sys +import traceback import getopt import tempfile import zlib @@ -220,20 +222,30 @@ def get_serials2(path=STORAGE2): userdata_keys = cursor.fetchall() dsns = [] for userdata_row in userdata_keys: - if userdata_row: - userdata_utf8 = userdata_row[0].encode('utf8') - if len(userdata_utf8) > 0: - dsns.append(userdata_utf8) + try: + if userdata_row and userdata_row[0]: + userdata_utf8 = userdata_row[0].encode('utf8') + if len(userdata_utf8) > 0: + dsns.append(userdata_utf8) + except: + print "Error getting one of the device serial name keys" + traceback.print_exc() + pass dsns = list(set(dsns)) cursor.execute('''select userdata_value from userdata where userdata_key like '%/%kindle.account.tokens%' ''') userdata_keys = cursor.fetchall() tokens = [] for userdata_row in userdata_keys: - if userdata_row: - userdata_utf8 = userdata_row[0].encode('utf8') - if len(userdata_utf8) > 0: - tokens.append(userdata_utf8) + try: + if userdata_row and userdata_row[0]: + userdata_utf8 = userdata_row[0].encode('utf8') + if len(userdata_utf8) > 0: + tokens.append(userdata_utf8) + except: + print "Error getting one of the account token keys" + traceback.print_exc() + pass tokens = list(set(tokens)) serials = [] @@ -377,7 +389,6 @@ def gui_main(): import Tkconstants import tkMessageBox import tkFileDialog - import traceback except: print "Tkinter not installed" return cli_main() diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/DeDRM_App.pyw b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/DeDRM_App.pyw index 45c9e06..87b8634 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/DeDRM_App.pyw +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/DeDRM_App.pyw @@ -18,8 +18,9 @@ # 6.3.1 - Version bump for clarity # 6.3.2 - Version bump to match plugin # 6.3.3 - Version bump to match plugin +# 6.3.4 - Version bump to match plugin -__version__ = '6.3.3' +__version__ = '6.3.4' import sys import os, os.path diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/__init__.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/__init__.py index 1f34cfe..53b1200 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/__init__.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/__init__.py @@ -45,6 +45,7 @@ __docformat__ = 'restructuredtext en' # 6.3.1 - Version number bump for clarity # 6.3.2 - Fixed Kindle for Android help file # 6.3.3 - Bug fix for Kindle for PC support +# 6.3.4 - Fixes for Kindle for Android, Linux, and Kobo 3.17 """ @@ -52,7 +53,7 @@ Decrypt DRMed ebooks. """ PLUGIN_NAME = u"DeDRM" -PLUGIN_VERSION_TUPLE = (6, 3, 3) +PLUGIN_VERSION_TUPLE = (6, 3, 4) 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' @@ -148,7 +149,7 @@ class DeDRM(FileTypePlugin): try: open(file_path,'wb').write(data) except: - print u"{0} v{1}: Exception when copying needed library files after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime) + print u"{0} v{1}: Exception when copying needed library files".format(PLUGIN_NAME, PLUGIN_VERSION) traceback.print_exc() pass diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/androidkindlekey.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/androidkindlekey.py index 2c539ee..ff8d1ee 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/androidkindlekey.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/androidkindlekey.py @@ -16,16 +16,18 @@ from __future__ import with_statement # - and added in unicode command line support # 1.3 - added in TkInter interface, output to a file # 1.4 - Fix some problems identified by Aldo Bleeker +# 1.5 - Fix another problem identified by Aldo Bleeker """ Retrieve Kindle for Android Serial Number. """ __license__ = 'GPL v3' -__version__ = '1.4' +__version__ = '1.5' import os import sys +import traceback import getopt import tempfile import zlib @@ -220,20 +222,30 @@ def get_serials2(path=STORAGE2): userdata_keys = cursor.fetchall() dsns = [] for userdata_row in userdata_keys: - if userdata_row: - userdata_utf8 = userdata_row[0].encode('utf8') - if len(userdata_utf8) > 0: - dsns.append(userdata_utf8) + try: + if userdata_row and userdata_row[0]: + userdata_utf8 = userdata_row[0].encode('utf8') + if len(userdata_utf8) > 0: + dsns.append(userdata_utf8) + except: + print "Error getting one of the device serial name keys" + traceback.print_exc() + pass dsns = list(set(dsns)) cursor.execute('''select userdata_value from userdata where userdata_key like '%/%kindle.account.tokens%' ''') userdata_keys = cursor.fetchall() tokens = [] for userdata_row in userdata_keys: - if userdata_row: - userdata_utf8 = userdata_row[0].encode('utf8') - if len(userdata_utf8) > 0: - tokens.append(userdata_utf8) + try: + if userdata_row and userdata_row[0]: + userdata_utf8 = userdata_row[0].encode('utf8') + if len(userdata_utf8) > 0: + tokens.append(userdata_utf8) + except: + print "Error getting one of the account token keys" + traceback.print_exc() + pass tokens = list(set(tokens)) serials = [] @@ -377,7 +389,6 @@ def gui_main(): import Tkconstants import tkMessageBox import tkFileDialog - import traceback except: print "Tkinter not installed" return cli_main() diff --git a/DeDRM_calibre_plugin/DeDRM_plugin.zip b/DeDRM_calibre_plugin/DeDRM_plugin.zip index 082e50888b339a0b8bd1f16e00a303de51073104..a64da23e1b9ded09f241d3e95a1b81e7993917df 100644 GIT binary patch delta 12535 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 F{{hz=n^^z= delta 12423 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 Q|7s&L1cba6@Zacv0AnLdZ2$lO diff --git a/DeDRM_calibre_plugin/DeDRM_plugin/__init__.py b/DeDRM_calibre_plugin/DeDRM_plugin/__init__.py index 1f34cfe..53b1200 100644 --- a/DeDRM_calibre_plugin/DeDRM_plugin/__init__.py +++ b/DeDRM_calibre_plugin/DeDRM_plugin/__init__.py @@ -45,6 +45,7 @@ __docformat__ = 'restructuredtext en' # 6.3.1 - Version number bump for clarity # 6.3.2 - Fixed Kindle for Android help file # 6.3.3 - Bug fix for Kindle for PC support +# 6.3.4 - Fixes for Kindle for Android, Linux, and Kobo 3.17 """ @@ -52,7 +53,7 @@ Decrypt DRMed ebooks. """ PLUGIN_NAME = u"DeDRM" -PLUGIN_VERSION_TUPLE = (6, 3, 3) +PLUGIN_VERSION_TUPLE = (6, 3, 4) 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' @@ -148,7 +149,7 @@ class DeDRM(FileTypePlugin): try: open(file_path,'wb').write(data) except: - print u"{0} v{1}: Exception when copying needed library files after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime) + print u"{0} v{1}: Exception when copying needed library files".format(PLUGIN_NAME, PLUGIN_VERSION) traceback.print_exc() pass diff --git a/DeDRM_calibre_plugin/DeDRM_plugin/androidkindlekey.py b/DeDRM_calibre_plugin/DeDRM_plugin/androidkindlekey.py index 2c539ee..ff8d1ee 100644 --- a/DeDRM_calibre_plugin/DeDRM_plugin/androidkindlekey.py +++ b/DeDRM_calibre_plugin/DeDRM_plugin/androidkindlekey.py @@ -16,16 +16,18 @@ from __future__ import with_statement # - and added in unicode command line support # 1.3 - added in TkInter interface, output to a file # 1.4 - Fix some problems identified by Aldo Bleeker +# 1.5 - Fix another problem identified by Aldo Bleeker """ Retrieve Kindle for Android Serial Number. """ __license__ = 'GPL v3' -__version__ = '1.4' +__version__ = '1.5' import os import sys +import traceback import getopt import tempfile import zlib @@ -220,20 +222,30 @@ def get_serials2(path=STORAGE2): userdata_keys = cursor.fetchall() dsns = [] for userdata_row in userdata_keys: - if userdata_row: - userdata_utf8 = userdata_row[0].encode('utf8') - if len(userdata_utf8) > 0: - dsns.append(userdata_utf8) + try: + if userdata_row and userdata_row[0]: + userdata_utf8 = userdata_row[0].encode('utf8') + if len(userdata_utf8) > 0: + dsns.append(userdata_utf8) + except: + print "Error getting one of the device serial name keys" + traceback.print_exc() + pass dsns = list(set(dsns)) cursor.execute('''select userdata_value from userdata where userdata_key like '%/%kindle.account.tokens%' ''') userdata_keys = cursor.fetchall() tokens = [] for userdata_row in userdata_keys: - if userdata_row: - userdata_utf8 = userdata_row[0].encode('utf8') - if len(userdata_utf8) > 0: - tokens.append(userdata_utf8) + try: + if userdata_row and userdata_row[0]: + userdata_utf8 = userdata_row[0].encode('utf8') + if len(userdata_utf8) > 0: + tokens.append(userdata_utf8) + except: + print "Error getting one of the account token keys" + traceback.print_exc() + pass tokens = list(set(tokens)) serials = [] @@ -377,7 +389,6 @@ def gui_main(): import Tkconstants import tkMessageBox import tkFileDialog - import traceback except: print "Tkinter not installed" return cli_main() diff --git a/Other_Tools/DRM_Key_Scripts/Kindle_for_Android/androidkindlekey.pyw b/Other_Tools/DRM_Key_Scripts/Kindle_for_Android/androidkindlekey.pyw index 2c539ee..ff8d1ee 100644 --- a/Other_Tools/DRM_Key_Scripts/Kindle_for_Android/androidkindlekey.pyw +++ b/Other_Tools/DRM_Key_Scripts/Kindle_for_Android/androidkindlekey.pyw @@ -16,16 +16,18 @@ from __future__ import with_statement # - and added in unicode command line support # 1.3 - added in TkInter interface, output to a file # 1.4 - Fix some problems identified by Aldo Bleeker +# 1.5 - Fix another problem identified by Aldo Bleeker """ Retrieve Kindle for Android Serial Number. """ __license__ = 'GPL v3' -__version__ = '1.4' +__version__ = '1.5' import os import sys +import traceback import getopt import tempfile import zlib @@ -220,20 +222,30 @@ def get_serials2(path=STORAGE2): userdata_keys = cursor.fetchall() dsns = [] for userdata_row in userdata_keys: - if userdata_row: - userdata_utf8 = userdata_row[0].encode('utf8') - if len(userdata_utf8) > 0: - dsns.append(userdata_utf8) + try: + if userdata_row and userdata_row[0]: + userdata_utf8 = userdata_row[0].encode('utf8') + if len(userdata_utf8) > 0: + dsns.append(userdata_utf8) + except: + print "Error getting one of the device serial name keys" + traceback.print_exc() + pass dsns = list(set(dsns)) cursor.execute('''select userdata_value from userdata where userdata_key like '%/%kindle.account.tokens%' ''') userdata_keys = cursor.fetchall() tokens = [] for userdata_row in userdata_keys: - if userdata_row: - userdata_utf8 = userdata_row[0].encode('utf8') - if len(userdata_utf8) > 0: - tokens.append(userdata_utf8) + try: + if userdata_row and userdata_row[0]: + userdata_utf8 = userdata_row[0].encode('utf8') + if len(userdata_utf8) > 0: + tokens.append(userdata_utf8) + except: + print "Error getting one of the account token keys" + traceback.print_exc() + pass tokens = list(set(tokens)) serials = [] @@ -377,7 +389,6 @@ def gui_main(): import Tkconstants import tkMessageBox import tkFileDialog - import traceback except: print "Tkinter not installed" return cli_main() diff --git a/ReadMe_First.txt b/ReadMe_First.txt index 5e3ad45..beb7287 100644 --- a/ReadMe_First.txt +++ b/ReadMe_First.txt @@ -1,7 +1,7 @@ Welcome to the tools! ===================== -This ReadMe_First.txt 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.3.1 archive from Apprentice Alf's Blog: http://apprenticealf.wordpress.com/ +This ReadMe_First.txt 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.3.4 archive from Apprentice Alf's Blog: http://apprenticealf.wordpress.com/ The is archive includes tools to remove DRM from: