mirror of
https://github.com/apprenticeharper/DeDRM_tools
synced 2024-12-28 09:58:56 +01:00
tools v6.0.5
This commit is contained in:
parent
cd2d74601a
commit
a399d3b7bd
13 changed files with 305 additions and 26 deletions
|
@ -24,7 +24,7 @@
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>droplet</string>
|
<string>droplet</string>
|
||||||
<key>CFBundleGetInfoString</key>
|
<key>CFBundleGetInfoString</key>
|
||||||
<string>DeDRM AppleScript 6.0.4. Written 2010–2013 by Apprentice Alf and others.</string>
|
<string>DeDRM AppleScript 6.0.5. Written 2010–2013 by Apprentice Alf and others.</string>
|
||||||
<key>CFBundleIconFile</key>
|
<key>CFBundleIconFile</key>
|
||||||
<string>DeDRM</string>
|
<string>DeDRM</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
|
@ -36,7 +36,7 @@
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>6.0.4</string>
|
<string>6.0.5</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>dplt</string>
|
<string>dplt</string>
|
||||||
<key>LSRequiresCarbon</key>
|
<key>LSRequiresCarbon</key>
|
||||||
|
|
|
@ -34,7 +34,7 @@ Decrypt DRMed ebooks.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
PLUGIN_NAME = u"DeDRM"
|
PLUGIN_NAME = u"DeDRM"
|
||||||
PLUGIN_VERSION_TUPLE = (6, 0, 2)
|
PLUGIN_VERSION_TUPLE = (6, 0, 5)
|
||||||
PLUGIN_VERSION = u".".join([unicode(str(x)) for x in PLUGIN_VERSION_TUPLE])
|
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.
|
# Include an html helpfile in the plugin's zipfile with the following name.
|
||||||
RESOURCE_NAME = PLUGIN_NAME + '_Help.htm'
|
RESOURCE_NAME = PLUGIN_NAME + '_Help.htm'
|
||||||
|
|
|
@ -6,7 +6,7 @@ from __future__ import with_statement
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
|
|
||||||
# Standard Python modules.
|
# Standard Python modules.
|
||||||
import os, traceback
|
import os, traceback, json
|
||||||
|
|
||||||
# PyQT4 modules (part of calibre).
|
# PyQT4 modules (part of calibre).
|
||||||
from PyQt4.Qt import (Qt, QWidget, QHBoxLayout, QVBoxLayout, QLabel, QLineEdit,
|
from PyQt4.Qt import (Qt, QWidget, QHBoxLayout, QVBoxLayout, QLabel, QLineEdit,
|
||||||
|
@ -178,8 +178,8 @@ class ManageKeysDialog(QDialog):
|
||||||
self.create_key = create_key
|
self.create_key = create_key
|
||||||
self.keyfile_ext = keyfile_ext
|
self.keyfile_ext = keyfile_ext
|
||||||
self.import_key = (keyfile_ext != u"")
|
self.import_key = (keyfile_ext != u"")
|
||||||
self.binary_file = (keyfile_ext == u".der")
|
self.binary_file = (keyfile_ext == u"der")
|
||||||
self.json_file = (keyfile_ext == u".k4i")
|
self.json_file = (keyfile_ext == u"k4i")
|
||||||
self.wineprefix = wineprefix
|
self.wineprefix = wineprefix
|
||||||
|
|
||||||
self.setWindowTitle("{0} {1}: Manage {2}s".format(PLUGIN_NAME, PLUGIN_VERSION, self.key_type_name))
|
self.setWindowTitle("{0} {1}: Manage {2}s".format(PLUGIN_NAME, PLUGIN_VERSION, self.key_type_name))
|
||||||
|
@ -676,7 +676,7 @@ class AddAdeptDialog(QDialog):
|
||||||
from calibre_plugins.dedrm.adobekey import adeptkeys
|
from calibre_plugins.dedrm.adobekey import adeptkeys
|
||||||
|
|
||||||
defaultkeys = adeptkeys()
|
defaultkeys = adeptkeys()
|
||||||
else: # linux
|
else: # linux
|
||||||
from wineutils import WineGetKeys
|
from wineutils import WineGetKeys
|
||||||
|
|
||||||
scriptpath = os.path.join(parent.parent.alfdir,u"adobekey.py")
|
scriptpath = os.path.join(parent.parent.alfdir,u"adobekey.py")
|
||||||
|
|
|
@ -71,7 +71,7 @@ def unicode_argv():
|
||||||
argvencoding = sys.stdin.encoding
|
argvencoding = sys.stdin.encoding
|
||||||
if argvencoding == None:
|
if argvencoding == None:
|
||||||
argvencoding = 'utf-8'
|
argvencoding = 'utf-8'
|
||||||
return [arg if (type(arg) == unicode) else unicode(arg,argvencoding) for arg in sys.argv]
|
return [arg if (type(arg) == unicode) else unicode(arg, argvencoding) for arg in sys.argv]
|
||||||
|
|
||||||
#global switch
|
#global switch
|
||||||
debug = False
|
debug = False
|
||||||
|
@ -92,12 +92,12 @@ class DrmException(Exception):
|
||||||
def zipUpDir(myzip, tdir, localname):
|
def zipUpDir(myzip, tdir, localname):
|
||||||
currentdir = tdir
|
currentdir = tdir
|
||||||
if localname != u"":
|
if localname != u"":
|
||||||
currentdir = os.path.join(currentdir,localname)
|
currentdir = os.path.join(currentdir, localname)
|
||||||
list = os.listdir(currentdir)
|
list = os.listdir(currentdir)
|
||||||
for file in list:
|
for file in list:
|
||||||
afilename = file
|
afilename = file
|
||||||
localfilePath = os.path.join(localname, afilename)
|
localfilePath = os.path.join(localname, afilename)
|
||||||
realfilePath = os.path.join(currentdir,file)
|
realfilePath = os.path.join(currentdir, file)
|
||||||
if os.path.isfile(realfilePath):
|
if os.path.isfile(realfilePath):
|
||||||
myzip.write(realfilePath, localfilePath)
|
myzip.write(realfilePath, localfilePath)
|
||||||
elif os.path.isdir(realfilePath):
|
elif os.path.isdir(realfilePath):
|
||||||
|
@ -116,7 +116,7 @@ def bookReadEncodedNumber(fo):
|
||||||
data = ord(fo.read(1))
|
data = ord(fo.read(1))
|
||||||
if data >= 0x80:
|
if data >= 0x80:
|
||||||
datax = (data & 0x7F)
|
datax = (data & 0x7F)
|
||||||
while data >= 0x80 :
|
while data >= 0x80:
|
||||||
data = ord(fo.read(1))
|
data = ord(fo.read(1))
|
||||||
datax = (datax <<7) + (data & 0x7F)
|
datax = (datax <<7) + (data & 0x7F)
|
||||||
data = datax
|
data = datax
|
||||||
|
|
|
@ -10,8 +10,9 @@
|
||||||
# 6.0.2 - Fixed problem with spaces in paths and the bat file
|
# 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.3 - Fix for Windows non-ascii user names
|
||||||
# 6.0.4 - Fix for other potential unicode problems
|
# 6.0.4 - Fix for other potential unicode problems
|
||||||
|
# 6.0.5 - Fix typo
|
||||||
|
|
||||||
__version__ = '6.0.4'
|
__version__ = '6.0.5'
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os, os.path
|
import os, os.path
|
||||||
|
|
|
@ -27,14 +27,17 @@ __docformat__ = 'restructuredtext en'
|
||||||
# Revision history:
|
# Revision history:
|
||||||
# 6.0.0 - Initial release
|
# 6.0.0 - Initial release
|
||||||
# 6.0.1 - Bug Fixes for Windows App, Kindle for Mac and Windows Adobe Digital Editions
|
# 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.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Decrypt DRMed ebooks.
|
Decrypt DRMed ebooks.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
PLUGIN_NAME = u"DeDRM"
|
PLUGIN_NAME = u"DeDRM"
|
||||||
PLUGIN_VERSION_TUPLE = (6, 0, 2)
|
PLUGIN_VERSION_TUPLE = (6, 0, 5)
|
||||||
PLUGIN_VERSION = u".".join([unicode(str(x)) for x in PLUGIN_VERSION_TUPLE])
|
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.
|
# Include an html helpfile in the plugin's zipfile with the following name.
|
||||||
RESOURCE_NAME = PLUGIN_NAME + '_Help.htm'
|
RESOURCE_NAME = PLUGIN_NAME + '_Help.htm'
|
||||||
|
@ -426,7 +429,7 @@ class DeDRM(FileTypePlugin):
|
||||||
import calibre_plugins.dedrm.prefs as prefs
|
import calibre_plugins.dedrm.prefs as prefs
|
||||||
import calibre_plugins.dedrm.erdr2pml
|
import calibre_plugins.dedrm.erdr2pml
|
||||||
|
|
||||||
dedrmrefs = prefs.DeDRM_Prefs()
|
dedrmprefs = prefs.DeDRM_Prefs()
|
||||||
# Attempt to decrypt epub with each encryption key (generated or provided).
|
# Attempt to decrypt epub with each encryption key (generated or provided).
|
||||||
for keyname, userkey in dedrmprefs['ereaderkeys'].items():
|
for keyname, userkey in dedrmprefs['ereaderkeys'].items():
|
||||||
keyname_masked = u"".join((u'X' if (x.isdigit()) else x) for x in keyname)
|
keyname_masked = u"".join((u'X' if (x.isdigit()) else x) for x in keyname)
|
||||||
|
|
|
@ -6,7 +6,7 @@ from __future__ import with_statement
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
|
|
||||||
# Standard Python modules.
|
# Standard Python modules.
|
||||||
import os, traceback
|
import os, traceback, json
|
||||||
|
|
||||||
# PyQT4 modules (part of calibre).
|
# PyQT4 modules (part of calibre).
|
||||||
from PyQt4.Qt import (Qt, QWidget, QHBoxLayout, QVBoxLayout, QLabel, QLineEdit,
|
from PyQt4.Qt import (Qt, QWidget, QHBoxLayout, QVBoxLayout, QLabel, QLineEdit,
|
||||||
|
@ -178,8 +178,8 @@ class ManageKeysDialog(QDialog):
|
||||||
self.create_key = create_key
|
self.create_key = create_key
|
||||||
self.keyfile_ext = keyfile_ext
|
self.keyfile_ext = keyfile_ext
|
||||||
self.import_key = (keyfile_ext != u"")
|
self.import_key = (keyfile_ext != u"")
|
||||||
self.binary_file = (keyfile_ext == u".der")
|
self.binary_file = (keyfile_ext == u"der")
|
||||||
self.json_file = (keyfile_ext == u".k4i")
|
self.json_file = (keyfile_ext == u"k4i")
|
||||||
self.wineprefix = wineprefix
|
self.wineprefix = wineprefix
|
||||||
|
|
||||||
self.setWindowTitle("{0} {1}: Manage {2}s".format(PLUGIN_NAME, PLUGIN_VERSION, self.key_type_name))
|
self.setWindowTitle("{0} {1}: Manage {2}s".format(PLUGIN_NAME, PLUGIN_VERSION, self.key_type_name))
|
||||||
|
@ -676,7 +676,7 @@ class AddAdeptDialog(QDialog):
|
||||||
from calibre_plugins.dedrm.adobekey import adeptkeys
|
from calibre_plugins.dedrm.adobekey import adeptkeys
|
||||||
|
|
||||||
defaultkeys = adeptkeys()
|
defaultkeys = adeptkeys()
|
||||||
else: # linux
|
else: # linux
|
||||||
from wineutils import WineGetKeys
|
from wineutils import WineGetKeys
|
||||||
|
|
||||||
scriptpath = os.path.join(parent.parent.alfdir,u"adobekey.py")
|
scriptpath = os.path.join(parent.parent.alfdir,u"adobekey.py")
|
||||||
|
|
Binary file not shown.
|
@ -37,7 +37,7 @@ Decrypt DRMed ebooks.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
PLUGIN_NAME = u"DeDRM"
|
PLUGIN_NAME = u"DeDRM"
|
||||||
PLUGIN_VERSION_TUPLE = (6, 0, 4)
|
PLUGIN_VERSION_TUPLE = (6, 0, 5)
|
||||||
PLUGIN_VERSION = u".".join([unicode(str(x)) for x in PLUGIN_VERSION_TUPLE])
|
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.
|
# Include an html helpfile in the plugin's zipfile with the following name.
|
||||||
RESOURCE_NAME = PLUGIN_NAME + '_Help.htm'
|
RESOURCE_NAME = PLUGIN_NAME + '_Help.htm'
|
||||||
|
|
|
@ -6,7 +6,7 @@ from __future__ import with_statement
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
|
|
||||||
# Standard Python modules.
|
# Standard Python modules.
|
||||||
import os, traceback
|
import os, traceback, json
|
||||||
|
|
||||||
# PyQT4 modules (part of calibre).
|
# PyQT4 modules (part of calibre).
|
||||||
from PyQt4.Qt import (Qt, QWidget, QHBoxLayout, QVBoxLayout, QLabel, QLineEdit,
|
from PyQt4.Qt import (Qt, QWidget, QHBoxLayout, QVBoxLayout, QLabel, QLineEdit,
|
||||||
|
@ -178,8 +178,8 @@ class ManageKeysDialog(QDialog):
|
||||||
self.create_key = create_key
|
self.create_key = create_key
|
||||||
self.keyfile_ext = keyfile_ext
|
self.keyfile_ext = keyfile_ext
|
||||||
self.import_key = (keyfile_ext != u"")
|
self.import_key = (keyfile_ext != u"")
|
||||||
self.binary_file = (keyfile_ext == u".der")
|
self.binary_file = (keyfile_ext == u"der")
|
||||||
self.json_file = (keyfile_ext == u".k4i")
|
self.json_file = (keyfile_ext == u"k4i")
|
||||||
self.wineprefix = wineprefix
|
self.wineprefix = wineprefix
|
||||||
|
|
||||||
self.setWindowTitle("{0} {1}: Manage {2}s".format(PLUGIN_NAME, PLUGIN_VERSION, self.key_type_name))
|
self.setWindowTitle("{0} {1}: Manage {2}s".format(PLUGIN_NAME, PLUGIN_VERSION, self.key_type_name))
|
||||||
|
@ -676,7 +676,7 @@ class AddAdeptDialog(QDialog):
|
||||||
from calibre_plugins.dedrm.adobekey import adeptkeys
|
from calibre_plugins.dedrm.adobekey import adeptkeys
|
||||||
|
|
||||||
defaultkeys = adeptkeys()
|
defaultkeys = adeptkeys()
|
||||||
else: # linux
|
else: # linux
|
||||||
from wineutils import WineGetKeys
|
from wineutils import WineGetKeys
|
||||||
|
|
||||||
scriptpath = os.path.join(parent.parent.alfdir,u"adobekey.py")
|
scriptpath = os.path.join(parent.parent.alfdir,u"adobekey.py")
|
||||||
|
|
|
@ -114,7 +114,7 @@ def convertprefs(always = False):
|
||||||
# Generate eReader user key from name and credit card number.
|
# Generate eReader user key from name and credit card number.
|
||||||
keyname = u"{0}_{1}".format(name.strip(),cc.strip()[-4:])
|
keyname = u"{0}_{1}".format(name.strip(),cc.strip()[-4:])
|
||||||
keyvalue = getuser_key(name,cc).encode('hex')
|
keyvalue = getuser_key(name,cc).encode('hex')
|
||||||
userkeysappend([keyname,keyvalue])
|
userkeys.append([keyname,keyvalue])
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
print e.args[0]
|
print e.args[0]
|
||||||
|
|
275
Other_Tools/DRM_Key_Scripts/Kindle_for_iOS/kindleiospidgen.py
Normal file
275
Other_Tools/DRM_Key_Scripts/Kindle_for_iOS/kindleiospidgen.py
Normal file
|
@ -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 <skochinsky@mail.ru>
|
||||||
|
|
||||||
|
# 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] <email address> <MAC address> [<outfile>]".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())
|
|
@ -1,7 +1,7 @@
|
||||||
Welcome to the tools!
|
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.0.4 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.0.5 archive from Apprentice Alf's Blog: http://apprenticealf.wordpress.com/
|
||||||
|
|
||||||
The is archive includes tools to remove DRM from:
|
The is archive includes tools to remove DRM from:
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue