diff --git a/DeDRM_Macintosh_Application/DeDRM ReadMe.rtf b/DeDRM_Macintosh_Application/DeDRM ReadMe.rtf index 95e8b32..aa9043b 100644 Binary files a/DeDRM_Macintosh_Application/DeDRM ReadMe.rtf and b/DeDRM_Macintosh_Application/DeDRM ReadMe.rtf differ diff --git a/DeDRM_Macintosh_Application/DeDRM.app.txt b/DeDRM_Macintosh_Application/DeDRM.app.txt index e79ff4e..fdf0a43 100644 Binary files a/DeDRM_Macintosh_Application/DeDRM.app.txt and b/DeDRM_Macintosh_Application/DeDRM.app.txt differ diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist index 2beb96d..1d01a8a 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.0 Written 2010–2015 by Apprentice Alf et al. + DeDRM AppleScript 6.3.1 Written 2010–2015 by Apprentice Alf et al. CFBundleIconFile DeDRM CFBundleIdentifier @@ -36,7 +36,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 6.3.0 + 6.3.1 CFBundleSignature dplt LSRequiresCarbon @@ -48,6 +48,7 @@ bundleDividerCollapsed bundlePositionOfDivider + 1162 dividerCollapsed eventLogLevel @@ -55,9 +56,9 @@ name ScriptWindowState positionOfDivider - 439 + 652 savedFrame - 128 98 1246 778 0 0 1680 1027 + 0 36 1680 991 0 0 1680 1027 selectedTab log diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/Scripts/main.scpt b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/Scripts/main.scpt index 3993b61..c09575e 100644 Binary files a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/Scripts/main.scpt and b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/Scripts/main.scpt differ diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py index 5919f5b..6992561 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py @@ -42,6 +42,7 @@ __docformat__ = 'restructuredtext en' # 6.2.1 - Fix for non-ascii Windows user names # 6.2.2 - Added URL method for B&N/nook books # 6.3.0 - Added in Kindle for Android serial number solution +# 6.3.1 - Version number bump for clarity """ @@ -49,7 +50,7 @@ Decrypt DRMed ebooks. """ PLUGIN_NAME = u"DeDRM" -PLUGIN_VERSION_TUPLE = (6, 3, 0) +PLUGIN_VERSION_TUPLE = (6, 3, 1) 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' 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 index 2b42b22..e9c3bc1 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/description.rtfd/TXT.rtf +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/description.rtfd/TXT.rtf @@ -1,4 +1,4 @@ -{\rtf1\ansi\ansicpg1252\cocoartf1343\cocoasubrtf160 +{\rtf1\ansi\ansicpg1252\cocoartf1348\cocoasubrtf170 {\fonttbl} {\colortbl;\red255\green255\blue255;} } \ No newline at end of file diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ignoblekeyfetch.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ignoblekeyfetch.py index c91e6f3..e9637a1 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ignoblekeyfetch.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ignoblekeyfetch.py @@ -30,7 +30,7 @@ Fetch Barnes & Noble EPUB user key from B&N servers using email and password """ __license__ = 'GPL v3' -__version__ = "1.0" +__version__ = "1.1" import sys import os @@ -101,23 +101,23 @@ class IGNOBLEError(Exception): pass def fetch_key(email, password): - # change name and CC numbers to utf-8 if unicode + # change email and password to utf-8 if unicode if type(email)==unicode: email = email.encode('utf-8') if type(password)==unicode: password = password.encode('utf-8') - + import random random = "%030x" % random.randrange(16**30) - + import urllib, urllib2, re - + # try the URL from nook for PC fetch_url = "https://cart4.barnesandnoble.com/services/service.aspx?Version=2&acctPassword=" fetch_url += urllib.quote(password,'')+"&devID=PC_BN_2.5.6.9575_"+random+"&emailAddress=" fetch_url += urllib.quote(email,"")+"&outFormat=5&schema=1&service=1&stage=deviceHashB" #print fetch_url - + found = '' try: req = urllib2.Request(fetch_url) @@ -133,13 +133,13 @@ def fetch_key(email, password): fetch_url += urllib.quote(password,'')+"&devID=hobbes_9.3.50818_"+random+"&emailAddress=" fetch_url += urllib.quote(email,"")+"&outFormat=5&schema=1&service=1&stage=deviceHashB" #print fetch_url - + found = '' try: req = urllib2.Request(fetch_url) response = urllib2.urlopen(req) the_page = response.read() - #print the_page + #print the_page found = re.search('ccHash>(.+?)(.+?)(.+?) # Based on discoveries by "Nobody You Know" +# Code partly based on ignoblekeygen.py by several people. # Windows users: Before running this program, you must first install Python. # We recommend ActiveState Python 2.7.X for Windows from @@ -17,18 +18,19 @@ from __future__ import with_statement # Then save this script file as ignoblekeyfetch.pyw and double-click on it to run it. # # Mac OS X users: Save this script file as ignoblekeyfetch.pyw. You can run this -# program from the command line (python ignoblekeygen.pyw) or by double-clicking +# program from the command line (python ignoblekeyfetch.pyw) or by double-clicking # it when it has been associated with PythonLauncher. # Revision history: -# 1.0 - Initial release +# 1.0 - Initial version +# 1.1 - Try second URL if first one fails """ Fetch Barnes & Noble EPUB user key from B&N servers using email and password """ __license__ = 'GPL v3' -__version__ = "1.0" +__version__ = "1.1" import sys import os @@ -87,7 +89,7 @@ def unicode_argv(): xrange(start, argc.value)] # if we don't have any arguments at all, just pass back script name # this should never happen - return [u"ignoblekeygen.py"] + return [u"ignoblekeyfetch.py"] else: argvencoding = sys.stdin.encoding if argvencoding == None: @@ -99,33 +101,49 @@ class IGNOBLEError(Exception): pass def fetch_key(email, password): - # remove spaces and case from name and CC numbers. + # change email and password to utf-8 if unicode if type(email)==unicode: email = email.encode('utf-8') if type(password)==unicode: password = password.encode('utf-8') - + import random random = "%030x" % random.randrange(16**30) - - import urllib, urllib2 + + import urllib, urllib2, re + + # try the URL from nook for PC fetch_url = "https://cart4.barnesandnoble.com/services/service.aspx?Version=2&acctPassword=" fetch_url += urllib.quote(password,'')+"&devID=PC_BN_2.5.6.9575_"+random+"&emailAddress=" fetch_url += urllib.quote(email,"")+"&outFormat=5&schema=1&service=1&stage=deviceHashB" #print fetch_url - + found = '' try: req = urllib2.Request(fetch_url) response = urllib2.urlopen(req) the_page = response.read() #print the_page - - import re - found = re.search('ccHash>(.+?)(.+?) 0: + dsns.append(userdata_utf8) + dsns = list(set(dsns)) cursor.execute('''select userdata_value from userdata where userdata_key like '%/%kindle.account.tokens%' ''') - tokens = [x[0].encode('utf8') for x in cursor.fetchall()] + 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) + tokens = list(set(tokens)) + serials = [] for x in dsns: + serials.append(x) for y in tokens: serials.append('%s%s' % (x, y)) + for y in tokens: + serials.append(y) return serials def get_serials(path=STORAGE): @@ -269,46 +291,31 @@ def get_serials(path=STORAGE): write_path = os.path.abspath(write.name) serials.extend(get_serials2(write_path)) os.remove(write_path) - - return serials + return list(set(serials)) __all__ = [ 'get_serials', 'getkey'] -# interface for Python DeDRM -# returns single key or multiple keys, depending on path or file passed in -def getkey(outpath, inpath): +# procedure for CLI and GUI interfaces +# returns single or multiple keys (one per line) in the specified file +def getkey(outfile, inpath): keys = get_serials(inpath) 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 + with file(outfile, 'w') as keyfileout: for key in keys: - while True: - keycount += 1 - outfile = os.path.join(outpath,u"kindlekey{0:d}.k4a".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) + keyfileout.write(key) + keyfileout.write("\n") return True return False def usage(progname): - print u"{0} v{1}\nCopyright © 2013-2015 Thom and Apprentice Harper".format(progname,__version__) - print u"Decrypts the serial number of Kindle For Android from Android backup or file" + print u"Decrypts the serial number(s) of Kindle For Android from Android backup or file" print u"Get backup.ab file using adb backup com.amazon.kindle for Android 4.0+." print u"Otherwise extract AmazonSecureStorage.xml from /data/data/com.amazon.kindle/shared_prefs/AmazonSecureStorage.xml" print u"Or map_data_storage.db from /data/data/com.amazon.kindle/databases/map_data_storage.db" print u"" - print u"Serial number is written to standard output." print u"Usage:" - print u" {0:s} [-h] [-b ] []".format(progname) + print u" {0:s} [-h] [-b ] []".format(progname) def cli_main(): @@ -339,24 +346,28 @@ def cli_main(): if len(args) == 1: # save to the specified file or directory - outpath = args[0] - if not os.path.isabs(outpath): - outpath = os.path.join(os.path.dirname(argv[0]),outpath) - outpath = os.path.abspath(outpath) + outfile = args[0] + if not os.path.isabs(outfile): + outfile = os.path.join(os.path.dirname(argv[0]),outfile) + outfile = os.path.abspath(outfile) + if os.path.isdir(outfile): + outfile = os.path.join(os.path.dirname(argv[0]),"androidkindlekey.k4a") else: # save to the same directory as the script - outpath = os.path.dirname(argv[0]) + outfile = os.path.join(os.path.dirname(argv[0]),"androidkindlekey.k4a") # make sure the outpath is OK - outpath = os.path.realpath(os.path.normpath(outpath)) + outfile = os.path.realpath(os.path.normpath(outfile)) if not os.path.isfile(inpath): usage(progname) print u"\n{0:s} file not found".format(inpath) return 2 - if not getkey(outpath, inpath): - print u"Could not retrieve Kindle for Android key." + if getkey(outfile, inpath): + print u"\nSaved Kindle for Android key to {0}".format(outfile) + else: + print u"\nCould not retrieve Kindle for Android key." return 0 diff --git a/Other_Tools/Kindle_for_Android_Patches/A_Patching_Experience.txt b/Other_Tools/Kindle_for_Android_Patches/A_Patching_Experience.txt index d28a96a..0c24f0d 100644 --- a/Other_Tools/Kindle_for_Android_Patches/A_Patching_Experience.txt +++ b/Other_Tools/Kindle_for_Android_Patches/A_Patching_Experience.txt @@ -1,3 +1,14 @@ +Of Historical Interest Only +=========================== + +It is now much simpler and easier to get a backup.ab file from your Android device and import that into the tools. + + + + + + + Comment at Apprentice Alf's Blog by cestmoicestmoi, 21st December, 2012. ======================================================================== diff --git a/README.md b/README.md index e81a8a5..4dbe0ee 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,8 @@ Mostly it tracks the tools releases by Apprentice Alf, athough it also includes Users should download the latest zip archive. Developers might be interested in forking the repository, as it contains unzipped versions of those tools that are zipped, and text versions of the AppleScripts, to make the changes over time easier to follow. -I welcome contributions from others to improve these tools, from expanding the range of books handled, improving key retrieval, to just general bug fixe, speed improvements and UI enhancements. +I welcome contributions from others to improve these tools, from expanding the range of books handled, improving key retrieval, to just general bug fixes, speed improvements and UI enhancements. -My special thanks to all those developers who have done the hard work of reverse engineering to provide the initial tools. +My special thanks to all those developers who have done the hard work of reverse engineering to provide the initial tools. Apprentice Harper. diff --git a/ReadMe_First.txt b/ReadMe_First.txt index 22af920..5e3ad45 100644 --- a/ReadMe_First.txt +++ b/ReadMe_First.txt @@ -1,11 +1,11 @@ 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.2.2 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.1 archive from Apprentice Alf's Blog: http://apprenticealf.wordpress.com/ The is archive includes tools to remove DRM from: - - Kindle ebooks (Mobi, Topaz, Print Replica and KF8). + - Kindle ebooks (from Kindle for Mac/PC, eInk Kindles and Kindle for Android). - Barnes and Noble ePubs - Adobe Digital Editions ePubs (including Kobo and Google ePubs downloaded to ADE) - Kobo kePubs from the Kobo Desktop application @@ -36,7 +36,7 @@ DeDRM application for Mac OS X users: (Mac OS X 10.4 and above) --------------------------------------------------------------- This application is a stand-alone DRM removal application for Mac OS X users. -For instructions, see the "DeDRM ReadMe.rtf" file in the DeDRM_Application_Macintosh folder. +For instructions, see the "DeDRM ReadMe.rtf" file in the DeDRM_Macintosh_Application folder. N.B. Mac OS X 10.4 users need to take extra steps before using the application, see the ReadMe. @@ -62,17 +62,14 @@ Other_Tools ----------- This is a folder of other tools that may be useful for DRMed ebooks from certain sources or for Linux users. Most users won't need any of these tools. -DRM_Key_Scripts -This folder contains python scripts that create or extract or fetch encryption keyfiles for Barnes and Noble ePubs, Adobe Digital Editions ePubs, Kindle for Mac/PC and Kindle for Android ebooks. These files are needed for the Windows stand-alone DeDRM application. - -B&N_Download_Helper +B_and_N_Download_Helper A Javascript to enable a download button at the B&N website for ebooks that normally won't download to your PC. Only for the adventurous. DRM_Key_Scripts This folder contains python scripts that create or extract or fetch encryption keyfiles for Barnes and Noble ePubs, Adobe Digital Editions ePubs, Kindle for Mac/PC and Kindle for Android ebooks. Kindle_for_Android_Patches -Definitely only for the adventurous, this folder contains information on how to modify the Kindel for Android app to b able to get a PID for use with the other Kindle tools (DeDRM apps and calibre plugin). +Definitely only for the adventurous, this folder contains information on how to modify the Kindle for Android app to b able to get a PID for use with the other Kindle tools (DeDRM apps and calibre plugin). This is now of historical interest only, as Android support has now been added to the tools more simply. Kobo Contains the standalone obok python script for removing DRM from kePubs downloaded using the kobo desktop application.