New approach to Android backup files. Changed version number to 6.3.1

This commit is contained in:
apprenticeharper
2015-08-02 11:09:35 +01:00
parent f5e66d42a1
commit aa822de138
24 changed files with 158 additions and 105 deletions

View File

@@ -3,13 +3,14 @@
from __future__ import with_statement
# ignoblekeyfetch.pyw, version 1.0
# ignoblekeyfetch.pyw, version 1.1
# Copyright © 2015 Apprentice Harper
# Released under the terms of the GNU General Public Licence, version 3
# <http://www.gnu.org/licenses/>
# 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>(.+?)</ccHash', the_page).group(1)
except:
found = ''
if len(found)!=28:
# try the URL from android devices
fetch_url = "https://cart4.barnesandnoble.com/services/service.aspx?Version=2&acctPassword="
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
found = re.search('ccHash>(.+?)</ccHash', the_page).group(1)
except:
found = ''
return found
@@ -151,6 +169,7 @@ def cli_main():
def gui_main():
try:
import Tkinter
import tkFileDialog
import Tkconstants
import tkMessageBox
import traceback

View File

@@ -33,13 +33,14 @@ from __future__ import with_statement
# 2.5 - Additional improvement for unicode and plugin support
# 2.6 - moved unicode_argv call inside main for Windows DeDRM compatibility
# 2.7 - Work if TkInter is missing
# 2.8 - Fix bug in stand-alone use (import tkFileDialog)
"""
Generate Barnes & Noble EPUB user key from name and credit card number.
"""
__license__ = 'GPL v3'
__version__ = "2.7"
__version__ = "2.8"
import sys
import os

View File

@@ -14,14 +14,15 @@ from __future__ import with_statement
# 1.2 - Changed to be callable from AppleScript by returning only serial number
# - and changed name to androidkindlekey.py
# - and added in unicode command line support
# 1.3 - added in TkInter interface, output to a file and attempt to get backup from a connected android device.
# 1.3 - added in TkInter interface, output to a file
# 1.4 - Fix some problems identified by Aldo Bleeker
"""
Retrieve Kindle for Android Serial Number.
"""
__license__ = 'GPL v3'
__version__ = '1.3'
__version__ = '1.4'
import os
import sys
@@ -199,13 +200,16 @@ def get_serials1(path=STORAGE1):
return []
serials = []
if dsnid:
serials.append(dsnid)
for token in tokens:
if token:
serials.append('%s%s' % (dsnid, token))
serials.append(token)
return serials
def get_serials2(path=STORAGE2):
''' get serials from android's shared preference xml '''
''' get serials from android's sql database '''
if not os.path.isfile(path):
return []
@@ -213,14 +217,32 @@ def get_serials2(path=STORAGE2):
connection = sqlite3.connect(path)
cursor = connection.cursor()
cursor.execute('''select userdata_value from userdata where userdata_key like '%/%token.device.deviceserialname%' ''')
dsns = [x[0].encode('utf8') for x in cursor.fetchall()]
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)
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 <backup.ab>] [<outpath>]".format(progname)
print u" {0:s} [-h] [-b <backup.ab>] [<outfile.k4a>]".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

View File

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