From 24f7ca219f3febb96c7a65c060eebcda3ca73684 Mon Sep 17 00:00:00 2001 From: Paul Durrant Date: Thu, 10 Jul 2008 20:30:03 +0100 Subject: [PATCH] First Applescript for calling python scripts --- .../eReader Unlocker.app/Contents/Info.plist | 50 ++ .../Contents/MacOS/droplet | Bin 0 -> 29592 bytes .../eReader Unlocker.app/Contents/PkgInfo | 1 + .../Contents/Resources/Scripts/main.scpt | Bin 0 -> 17026 bytes .../Contents/Resources/Scripts/main.scpt.txt | 59 +++ .../Resources/description.rtfd/TXT.rtf | 4 + .../Contents/Resources/droplet.icns | Bin 0 -> 40275 bytes .../Contents/Resources/droplet.rsrc | Bin 0 -> 362 bytes .../Contents/Resources/eReaderDeDRM.py | 493 ++++++++++++++++++ 9 files changed, 607 insertions(+) create mode 100644 Macintosh_Applications/eReader Unlocker.app/Contents/Info.plist create mode 100644 Macintosh_Applications/eReader Unlocker.app/Contents/MacOS/droplet create mode 100644 Macintosh_Applications/eReader Unlocker.app/Contents/PkgInfo create mode 100644 Macintosh_Applications/eReader Unlocker.app/Contents/Resources/Scripts/main.scpt create mode 100644 Macintosh_Applications/eReader Unlocker.app/Contents/Resources/Scripts/main.scpt.txt create mode 100644 Macintosh_Applications/eReader Unlocker.app/Contents/Resources/description.rtfd/TXT.rtf create mode 100644 Macintosh_Applications/eReader Unlocker.app/Contents/Resources/droplet.icns create mode 100644 Macintosh_Applications/eReader Unlocker.app/Contents/Resources/droplet.rsrc create mode 100644 Macintosh_Applications/eReader Unlocker.app/Contents/Resources/eReaderDeDRM.py diff --git a/Macintosh_Applications/eReader Unlocker.app/Contents/Info.plist b/Macintosh_Applications/eReader Unlocker.app/Contents/Info.plist new file mode 100644 index 0000000..2ae3b8a --- /dev/null +++ b/Macintosh_Applications/eReader Unlocker.app/Contents/Info.plist @@ -0,0 +1,50 @@ + + + + + CFBundleAllowMixedLocalizations + + CFBundleDevelopmentRegion + English + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + * + + CFBundleTypeOSTypes + + **** + + CFBundleTypeRole + Viewer + + + CFBundleExecutable + droplet + CFBundleIconFile + droplet + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + Mobipocket Unlocker + CFBundlePackageType + APPL + CFBundleSignature + dplt + LSRequiresCarbon + + WindowState + + name + ScriptWindowState + positionOfDivider + 627 + savedFrame + 53 78 661 691 0 0 1280 778 + selectedTabView + result + + + diff --git a/Macintosh_Applications/eReader Unlocker.app/Contents/MacOS/droplet b/Macintosh_Applications/eReader Unlocker.app/Contents/MacOS/droplet new file mode 100644 index 0000000000000000000000000000000000000000..c715860463c5434cb471de58b710cbe95976c23f GIT binary patch literal 29592 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 C-Wl!y literal 0 HcmV?d00001 diff --git a/Macintosh_Applications/eReader Unlocker.app/Contents/PkgInfo b/Macintosh_Applications/eReader Unlocker.app/Contents/PkgInfo new file mode 100644 index 0000000..b999e99 --- /dev/null +++ b/Macintosh_Applications/eReader Unlocker.app/Contents/PkgInfo @@ -0,0 +1 @@ +APPLdplt \ No newline at end of file diff --git a/Macintosh_Applications/eReader Unlocker.app/Contents/Resources/Scripts/main.scpt b/Macintosh_Applications/eReader Unlocker.app/Contents/Resources/Scripts/main.scpt new file mode 100644 index 0000000000000000000000000000000000000000..4e387a7eddb373a00d090fc28b9ce4419d22f959 GIT binary patch literal 17026 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 literal 0 HcmV?d00001 diff --git a/Macintosh_Applications/eReader Unlocker.app/Contents/Resources/Scripts/main.scpt.txt b/Macintosh_Applications/eReader Unlocker.app/Contents/Resources/Scripts/main.scpt.txt new file mode 100644 index 0000000..2161d02 --- /dev/null +++ b/Macintosh_Applications/eReader Unlocker.app/Contents/Resources/Scripts/main.scpt.txt @@ -0,0 +1,59 @@ +on unlockfile(encryptedFile, eReaderDeDRMPath, encryptionNameKey, encryptionKey) + set encryptedFilePath to POSIX path of file encryptedFile + tell application "Finder" to  + set parent_folder to (container of file encryptedFile) as text + tell application "Finder" to set fileName to (name of file encryptedFile) as text + set unlockedFilePath to POSIX path of file (parent_folder & "Unlocked_" & fileName) + set shellcommand to "python \"" & eReaderDeDRMPath & "\" \"" & encryptedFilePath & "\" \"" & unlockedFilePath & "\" \"" & encryptionNameKey & "\" " & encryptionKey + try + --with timeout of 5 seconds + --display dialog "About to Unlock " & fileName buttons {"Unlock"} default button 1 giving up after 1 + --end timeout + end try + set result to do shell script shellcommand + try + --with timeout of 5 seconds + --display dialog "Result" default answer result buttons ("OK") default button 1 --giving up after 2 + --end timeout + end try +end unlockfile + +on unlockfolder(encryptedFolder, eReaderDeDRMPath, encryptionNameKey, encryptionKey) + tell application "Finder" to set encryptedFileList to (every file in folder encryptedFolder) whose (name extension is "pdb") + tell application "Finder" to set encryptedFolderList to (every folder in folder encryptedFolder) + repeat with this_item in encryptedFileList + unlockfile(this_item as text, eReaderDeDRMPath, encryptionNameKey, encryptionKey) + end repeat + repeat with this_item in encryptedFolderList + unlockfolder(this_item as text, eReaderDeDRMPath, encryptionNameKey, encryptionKey) + end repeat +end unlockfolder + +on run + set eReaderDeDRMPath to POSIX path of file ((path to me as text) & "Contents:Resources:eReaderDeDRM.py") + set encryptedFolder to choose folder with prompt "Please choose the folder of encrypted eReader files." + set encryptionNameKey to (display dialog "Enter Name key for encrypted eReader files." default answer "MR PAUL M P DURRANT" buttons {"Cancel", "OK"} default button 2) + set encryptionKey to (display dialog "Enter Number key for encrypted eReader files." default answer "89940827" buttons {"Cancel", "OK"} default button 2) + set encryptionNameKey to text returned of encryptionNameKey + set encryptionKey to text returned of encryptionKey + unlockfolder(encryptedFolder, eReaderDeDRMPath, encryptionNameKey, encryptionKey) +end run + +on open some_items + set eReaderDeDRMPath to POSIX path of file ((path to me as text) & "Contents:Resources:eReaderDeDRM.py") + set encryptionNameKey to (display dialog "Enter Name key for encrypted eReader files." default answer "MR PAUL M P DURRANT" buttons {"Cancel", "OK"} default button 2) + set encryptionKey to (display dialog "Enter Number key for encrypted eReader files." default answer "89940827" buttons {"Cancel", "OK"} default button 2) + set encryptionNameKey to text returned of encryptionNameKey + set encryptionKey to text returned of encryptionKey + repeat with this_item in some_items + if (folder of (info for this_item) is true) then + unlockfolder(this_item as text, eReaderDeDRMPath, encryptionNameKey, encryptionKey) + else + tell application "Finder" to set item_extension to name extension of file this_item + if item_extension is "pdb" then + unlockfile(this_item as text, eReaderDeDRMPath, encryptionNameKey, encryptionKey) + end if + end if + end repeat +end open + diff --git a/Macintosh_Applications/eReader Unlocker.app/Contents/Resources/description.rtfd/TXT.rtf b/Macintosh_Applications/eReader Unlocker.app/Contents/Resources/description.rtfd/TXT.rtf new file mode 100644 index 0000000..19b3535 --- /dev/null +++ b/Macintosh_Applications/eReader Unlocker.app/Contents/Resources/description.rtfd/TXT.rtf @@ -0,0 +1,4 @@ +{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 +{\fonttbl} +{\colortbl;\red255\green255\blue255;} +} \ No newline at end of file diff --git a/Macintosh_Applications/eReader Unlocker.app/Contents/Resources/droplet.icns b/Macintosh_Applications/eReader Unlocker.app/Contents/Resources/droplet.icns new file mode 100644 index 0000000000000000000000000000000000000000..c2706de704e0709c5ee209639fa253c6b00a4a00 GIT binary patch literal 40275 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 literal 0 HcmV?d00001 diff --git a/Macintosh_Applications/eReader Unlocker.app/Contents/Resources/droplet.rsrc b/Macintosh_Applications/eReader Unlocker.app/Contents/Resources/droplet.rsrc new file mode 100644 index 0000000000000000000000000000000000000000..e6a4338eedbd6b5175ec410e44254c2127a52259 GIT binary patch literal 362 zcmZQzU}RumU{nDTAnXRjBMnG7;PWvPND?)STu$;c903W-0K<#1IJvkA$QCLtD9!-V UatsXr|AQoBfU2Nuxf~!H08r@;0{{R3 literal 0 HcmV?d00001 diff --git a/Macintosh_Applications/eReader Unlocker.app/Contents/Resources/eReaderDeDRM.py b/Macintosh_Applications/eReader Unlocker.app/Contents/Resources/eReaderDeDRM.py new file mode 100644 index 0000000..79f5215 --- /dev/null +++ b/Macintosh_Applications/eReader Unlocker.app/Contents/Resources/eReaderDeDRM.py @@ -0,0 +1,493 @@ +# This is a python script. You need a Python interpreter to run it. +# For example, ActiveState Python, which exists for windows. +# Changelog +# 0.01 - Initial version +# 0.02 - Support more eReader files. Support bold text and links. Fix PML decoder parsing bug. +# 0.03 - Fix incorrect variable usage at one place. + +import struct, binascii, zlib, os, sha, sys, os.path + +ECB = 0 +CBC = 1 +class Des: + __pc1 = [56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, + 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, + 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, + 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3] + __left_rotations = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1] + __pc2 = [13, 16, 10, 23, 0, 4,2, 27, 14, 5, 20, 9, + 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, + 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, + 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31] + __ip = [57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7, + 56, 48, 40, 32, 24, 16, 8, 0, 58, 50, 42, 34, 26, 18, 10, 2, + 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6] + __expansion_table = [31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, + 7, 8, 9, 10, 11, 12,11, 12, 13, 14, 15, 16, + 15, 16, 17, 18, 19, 20,19, 20, 21, 22, 23, 24, + 23, 24, 25, 26, 27, 28,27, 28, 29, 30, 31, 0] + __sbox = [[14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, + 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, + 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, + 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13], + [15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, + 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, + 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, + 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9], + [10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, + 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, + 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12], + [7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, + 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, + 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, + 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14], + [2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, + 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, + 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, + 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3], + [12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, + 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, + 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, + 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13], + [4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, + 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, + 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, + 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12], + [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, + 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, + 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, + 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11],] + __p = [15, 6, 19, 20, 28, 11,27, 16, 0, 14, 22, 25, + 4, 17, 30, 9, 1, 7,23,13, 31, 26, 2, 8,18, 12, 29, 5, 21, 10,3, 24] + __fp = [39, 7, 47, 15, 55, 23, 63, 31,38, 6, 46, 14, 54, 22, 62, 30, + 37, 5, 45, 13, 53, 21, 61, 29,36, 4, 44, 12, 52, 20, 60, 28, + 35, 3, 43, 11, 51, 19, 59, 27,34, 2, 42, 10, 50, 18, 58, 26, + 33, 1, 41, 9, 49, 17, 57, 25,32, 0, 40, 8, 48, 16, 56, 24] + # Type of crypting being done + ENCRYPT = 0x00 + DECRYPT = 0x01 + def __init__(self, key, mode=ECB, IV=None): + if len(key) != 8: + raise ValueError("Invalid DES key size. Key must be exactly 8 bytes long.") + self.block_size = 8 + self.key_size = 8 + self.__padding = '' + self.setMode(mode) + if IV: + self.setIV(IV) + self.L = [] + self.R = [] + self.Kn = [ [0] * 48 ] * 16 # 16 48-bit keys (K1 - K16) + self.final = [] + self.setKey(key) + def getKey(self): + return self.__key + def setKey(self, key): + self.__key = key + self.__create_sub_keys() + def getMode(self): + return self.__mode + def setMode(self, mode): + self.__mode = mode + def getIV(self): + return self.__iv + def setIV(self, IV): + if not IV or len(IV) != self.block_size: + raise ValueError("Invalid Initial Value (IV), must be a multiple of " + str(self.block_size) + " bytes") + self.__iv = IV + def getPadding(self): + return self.__padding + def __String_to_BitList(self, data): + l = len(data) * 8 + result = [0] * l + pos = 0 + for c in data: + i = 7 + ch = ord(c) + while i >= 0: + if ch & (1 << i) != 0: + result[pos] = 1 + else: + result[pos] = 0 + pos += 1 + i -= 1 + return result + def __BitList_to_String(self, data): + result = '' + pos = 0 + c = 0 + while pos < len(data): + c += data[pos] << (7 - (pos % 8)) + if (pos % 8) == 7: + result += chr(c) + c = 0 + pos += 1 + return result + def __permutate(self, table, block): + return map(lambda x: block[x], table) + def __create_sub_keys(self): + key = self.__permutate(Des.__pc1, self.__String_to_BitList(self.getKey())) + i = 0 + self.L = key[:28] + self.R = key[28:] + while i < 16: + j = 0 + while j < Des.__left_rotations[i]: + self.L.append(self.L[0]) + del self.L[0] + self.R.append(self.R[0]) + del self.R[0] + j += 1 + self.Kn[i] = self.__permutate(Des.__pc2, self.L + self.R) + i += 1 + def __des_crypt(self, block, crypt_type): + block = self.__permutate(Des.__ip, block) + self.L = block[:32] + self.R = block[32:] + if crypt_type == Des.ENCRYPT: + iteration = 0 + iteration_adjustment = 1 + else: + iteration = 15 + iteration_adjustment = -1 + i = 0 + while i < 16: + tempR = self.R[:] + self.R = self.__permutate(Des.__expansion_table, self.R) + self.R = map(lambda x, y: x ^ y, self.R, self.Kn[iteration]) + B = [self.R[:6], self.R[6:12], self.R[12:18], self.R[18:24], self.R[24:30], self.R[30:36], self.R[36:42], self.R[42:]] + j = 0 + Bn = [0] * 32 + pos = 0 + while j < 8: + m = (B[j][0] << 1) + B[j][5] + n = (B[j][1] << 3) + (B[j][2] << 2) + (B[j][3] << 1) + B[j][4] + v = Des.__sbox[j][(m << 4) + n] + Bn[pos] = (v & 8) >> 3 + Bn[pos + 1] = (v & 4) >> 2 + Bn[pos + 2] = (v & 2) >> 1 + Bn[pos + 3] = v & 1 + pos += 4 + j += 1 + self.R = self.__permutate(Des.__p, Bn) + self.R = map(lambda x, y: x ^ y, self.R, self.L) + self.L = tempR + i += 1 + iteration += iteration_adjustment + self.final = self.__permutate(Des.__fp, self.R + self.L) + return self.final + def crypt(self, data, crypt_type): + if not data: + return '' + if len(data) % self.block_size != 0: + if crypt_type == Des.DECRYPT: # Decryption must work on 8 byte blocks + raise ValueError("Invalid data length, data must be a multiple of " + str(self.block_size) + " bytes\n.") + if not self.getPadding(): + raise ValueError("Invalid data length, data must be a multiple of " + str(self.block_size) + " bytes\n. Try setting the optional padding character") + else: + data += (self.block_size - (len(data) % self.block_size)) * self.getPadding() + if self.getMode() == CBC: + if self.getIV(): + iv = self.__String_to_BitList(self.getIV()) + else: + raise ValueError("For CBC mode, you must supply the Initial Value (IV) for ciphering") + i = 0 + dict = {} + result = [] + while i < len(data): + block = self.__String_to_BitList(data[i:i+8]) + if self.getMode() == CBC: + if crypt_type == Des.ENCRYPT: + block = map(lambda x, y: x ^ y, block, iv) + processed_block = self.__des_crypt(block, crypt_type) + if crypt_type == Des.DECRYPT: + processed_block = map(lambda x, y: x ^ y, processed_block, iv) + iv = block + else: + iv = processed_block + else: + processed_block = self.__des_crypt(block, crypt_type) + result.append(self.__BitList_to_String(processed_block)) + i += 8 + if crypt_type == Des.DECRYPT and self.getPadding(): + s = result[-1] + while s[-1] == self.getPadding(): + s = s[:-1] + result[-1] = s + return ''.join(result) + def encrypt(self, data, pad=''): + self.__padding = pad + return self.crypt(data, Des.ENCRYPT) + def decrypt(self, data, pad=''): + self.__padding = pad + return self.crypt(data, Des.DECRYPT) + +class Sectionizer: + def __init__(self, filename, ident): + self.contents = file(filename, 'rb').read() + self.header = self.contents[0:72] + self.num_sections, = struct.unpack('>H', self.contents[76:78]) + if self.header[0x3C:0x3C+8] != ident: + raise ValueError('Invalid file format') + self.sections = [] + for i in xrange(self.num_sections): + offset, a1,a2,a3,a4 = struct.unpack('>LBBBB', self.contents[78+i*8:78+i*8+8]) + flags, val = a1, a2<<16|a3<<8|a4 + self.sections.append( (offset, flags, val) ) + def loadSection(self, section): + if section + 1 == self.num_sections: + end_off = len(self.contents) + else: + end_off = self.sections[section + 1][0] + off = self.sections[section][0] + return self.contents[off:end_off] + +def sanitizeFileName(s): + r = '' + for c in s.lower(): + if c in "abcdefghijklmnopqrstuvwxyz0123456789_.-": + r += c + return r + +def fixKey(key): + def fixByte(b): + return b ^ ((b ^ (b<<1) ^ (b<<2) ^ (b<<3) ^ (b<<4) ^ (b<<5) ^ (b<<6) ^ (b<<7) ^ 0x80) & 0x80) + return "".join([chr(fixByte(ord(a))) for a in key]) + +class EreaderProcessor: + def __init__(self, section_reader, username, creditcard): + self.section_reader = section_reader + data = section_reader(0) + version, = struct.unpack('>H', data[0:2]) + if version != 272 and version != 260: + raise ValueError('incorrect eReader version %d (error 1)' % version) + data = section_reader(1) + self.data = data + des = Des(fixKey(data[0:8])) + cookie_shuf, cookie_size = struct.unpack('>LL', des.decrypt(data[-8:])) + if cookie_shuf < 3 or cookie_shuf > 0x14 or cookie_size < 0xf0 or cookie_size > 0x200: + raise ValueError('incorrect eReader version (error 2)') + input = des.decrypt(data[-cookie_size:]) + def unshuff(data, shuf): + r = [''] * len(data) + j = 0 + for i in xrange(len(data)): + j = (j + shuf) % len(data) + r[j] = data[i] + assert len("".join(r)) == len(data) + return "".join(r) + r = unshuff(input[0:-8], cookie_shuf) + def fixUsername(s): + r = '' + for c in s.lower(): + if (c >= 'a' and c <= 'z' or c >= '0' and c <= '9'): + r += c + return r + user_key = struct.pack('>LL', binascii.crc32(fixUsername(username)) & 0xffffffff, binascii.crc32(creditcard[-8:])& 0xffffffff) + drm_sub_version = struct.unpack('>H', r[0:2])[0] + self.num_text_pages = struct.unpack('>H', r[2:4])[0] - 1 + self.num_image_pages = struct.unpack('>H', r[26:26+2])[0] + self.first_image_page = struct.unpack('>H', r[24:24+2])[0] + self.flags = struct.unpack('>L', r[4:8])[0] + reqd_flags = (1<<9) | (1<<7) | (1<<10) + if (self.flags & reqd_flags) != reqd_flags: + print "Flags: 0x%X" % self.flags + raise ValueError('incompatible eReader file') + des = Des(fixKey(user_key)) + if version == 260: + if drm_sub_version != 13: + raise ValueError('incorrect eReader version %d (error 3)' % drm_sub_version) + encrypted_key = r[44:44+8] + encrypted_key_sha = r[52:52+20] + elif version == 272: + encrypted_key = r[172:172+8] + encrypted_key_sha = r[56:56+20] + self.content_key = des.decrypt(encrypted_key) + if sha.new(self.content_key).digest() != encrypted_key_sha: + raise ValueError('Incorrect Name and/or Credit Card') + def getNumImages(self): + return self.num_image_pages + def getImage(self, i): + sect = self.section_reader(self.first_image_page + i) + name = sect[4:4+32].strip('\0') + data = sect[62:] + return sanitizeFileName(name), data + def getText(self): + des = Des(fixKey(self.content_key)) + r = '' + for i in xrange(self.num_text_pages): + r += zlib.decompress(des.decrypt(self.section_reader(1 + i))) + return r + +class PmlConverter: + def __init__(self, s): + self.s = s + self.pos = 0 + def nextOptAttr(self): + p = self.pos + if self.s[p:p+2] != '="': + return None + r = '' + p += 2 + while self.s[p] != '"': + r += self.s[p] + p += 1 + self.pos = p + 1 + return r + def next(self): + p = self.pos + if p >= len(self.s): + return None + if self.s[p] != '\\': + res = self.s.find('\\', p) + if res == -1: + res = len(self.s) + self.pos = res + return self.s[p : res], None, None + c = self.s[p+1] + if c in 'pxcriuovtnsblBk-lI\\d': + self.pos = p + 2 + return None, c, None + if c in 'TwmqQ': + self.pos = p + 2 + return None, c, self.nextOptAttr() + if c == 'a': + self.pos = p + 5 + return None, c, int(self.s[p+2:p+5]) + if c == 'U': + self.pos = p + 6 + return None, c, int(self.s[p+2:p+6], 16) + c = self.s[p+1:p+1+2] + if c in ('X0','X1','X2','X3','X4','Sp','Sb'): + self.pos = p + 3 + return None, c, None + if c in ('C0','C1','C2','C3','C4','Fn','Sd'): + self.pos = p + 3 + return None, c, self.nextOptAttr() + print "unknown escape code %s" % c + self.pos = p + 1 + return None, None, None + def linkPrinter(link): + return '' % link + + html_tags = { + 'c' : ('

', '

'), + 'r' : ('

', '

'), + 'i' : ('', ''), + 'u' : ('', ''), + 'b' : ('', ''), + 'B' : ('', ''), + 'o' : ('', ''), + 'v' : (''), + 't' : ('', ''), + 'Sb' : ('', ''), + 'Sp' : ('', ''), + 'X0' : ('

', '

'), + 'X1' : ('

', '

'), + 'X2' : ('

', '

'), + 'X3' : ('

', '

'), + 'X4' : ('
', '
'), + 'l' : ('', ''), + 'q' : (linkPrinter, '
'), + } + html_one_tags = { + 'p' : '

' + } + pml_chars = { + 160 : ' ',130 : '—',131: 'ƒ',132: '„', + 133: '…',134: '†',135: '‡',138: 'Š', + 139: '‹',140: 'Œ',145: '‘',146: '’', + 147: '“',148: '”',149: '•',150: '–', + 151: '—',153: '™',154: 'š',155: '›', + 156: 'œ',159: 'Ÿ' + } + def process(self): + final = '\n' + in_tags = [] + def makeText(s): + s = s.replace('&', '&') + #s = s.replace('"', '"') + s = s.replace('<', '<') + s = s.replace('>', '>') + s = s.replace('\n', '
\n') + return s + while True: + r = self.next() + if not r: + break + text, cmd, attr = r + if text: + final += makeText(text) + if cmd: + def getTag(ti, end): + cmd, attr = ti + r = self.html_tags[cmd][end] + if type(r) != str: + r = r(attr) + return r + + if cmd in self.html_tags: + pair = (cmd, attr) + if cmd not in [a for (a,b) in in_tags]: + final += getTag(pair, False) + in_tags.append(pair) + else: + j = len(in_tags) + while True: + j = j - 1 + final += getTag(in_tags[j], True) + if in_tags[j][0] == cmd: + break + del in_tags[j] + while j < len(in_tags): + final += getTag(in_tags[j], False) + j = j + 1 + + if cmd in self.html_one_tags: + final += self.html_one_tags[cmd] + if cmd == 'm': + final += '' % attr + if cmd == 'Q': + final += ' ' % attr + if cmd == 'a': + final += self.pml_chars.get(attr, '&#%d;' % attr) + if cmd == 'U': + final += '&#%d;' % attr + final += '\n' + while True: + s = final.replace('
\n
\n
\n', '
\n
\n') + if s == final: + break + final = s + return final + +def convertEreaderToHtml(infile, name, cc, outdir): + if not os.path.exists(outdir): + os.makedirs(outdir) + sect = Sectionizer(infile, 'PNRdPPrs') + er = EreaderProcessor(sect.loadSection, name, cc) + + for i in xrange(er.getNumImages()): + name, contents = er.getImage(i) + file(os.path.join(outdir, name), 'wb').write(contents) + + pml = PmlConverter(er.getText()) + file(os.path.join(outdir, 'book.html'),'wb').write(pml.process()) + +print "eReader2Html v0.03. Copyright (c) 2008 The Dark Reverser" +if len(sys.argv)!=5: + print "Converts eReader books to HTML" + print "Usage:" + print " ereader2html infile.pdb outdir \"your name\" credit_card_number " + print "Note:" + print " It's enough to enter the last 8 digits of the credit card number" +else: + infile, outdir, name, cc = sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4] + try: + print "Processing...", + convertEreaderToHtml(infile, name, cc, outdir) + print "done" + except ValueError, e: + print "Error: %s" % e \ No newline at end of file