From 1096e48342197386240e63dc3f846e8f0be3ce4c Mon Sep 17 00:00:00 2001 From: Paul Durrant Date: Wed, 27 Aug 2008 19:00:23 +0100 Subject: [PATCH] First Applescript for calling mobidedrm python script --- .../Mobipocket Unlocker ReadMe.txt | 55 ++++++ .../Contents/Info.plist | 50 +++++ .../Contents/MacOS/droplet | Bin 0 -> 29592 bytes .../Mobipocket Unlocker.app/Contents/PkgInfo | 1 + .../Contents/Resources/MobiDeDRM.py | 186 ++++++++++++++++++ .../Contents/Resources/Scripts/main.scpt | Bin 0 -> 15980 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 10 files changed, 355 insertions(+) create mode 100644 Macintosh_Applications/Mobipocket Unlocker ReadMe.txt create mode 100644 Macintosh_Applications/Mobipocket Unlocker.app/Contents/Info.plist create mode 100644 Macintosh_Applications/Mobipocket Unlocker.app/Contents/MacOS/droplet create mode 100644 Macintosh_Applications/Mobipocket Unlocker.app/Contents/PkgInfo create mode 100644 Macintosh_Applications/Mobipocket Unlocker.app/Contents/Resources/MobiDeDRM.py create mode 100644 Macintosh_Applications/Mobipocket Unlocker.app/Contents/Resources/Scripts/main.scpt create mode 100644 Macintosh_Applications/Mobipocket Unlocker.app/Contents/Resources/Scripts/main.scpt.txt create mode 100644 Macintosh_Applications/Mobipocket Unlocker.app/Contents/Resources/description.rtfd/TXT.rtf create mode 100644 Macintosh_Applications/Mobipocket Unlocker.app/Contents/Resources/droplet.icns create mode 100644 Macintosh_Applications/Mobipocket Unlocker.app/Contents/Resources/droplet.rsrc diff --git a/Macintosh_Applications/Mobipocket Unlocker ReadMe.txt b/Macintosh_Applications/Mobipocket Unlocker ReadMe.txt new file mode 100644 index 0000000..f672585 --- /dev/null +++ b/Macintosh_Applications/Mobipocket Unlocker ReadMe.txt @@ -0,0 +1,55 @@ +Mobipocket Unlocker AppleScript Version 3 + +How to get Drag&Drop decryption of DRM-encumbered Mobipocket eBook files. + +You'll need the MobiDeDRM.py python script, as well as an installed version 2.4 or later of python. If you have Mac OS X Leopard (10.5) you already have a suitable version of python installed as part of Leopard. + +Control-click the script and select "Show Package Contents" from the contextual menu. Copy the python script, which must be called "MobiDeDRM.py" into the Resources folder inside the Contents folder. (NB not into the Scripts folder - that's where the Applescript part is stored.) + +Close the package, and you now have a drag&drop Mobipocket decrypter. + +You can use the AppleScript ScriptEditor application to put your Mobipocket code into the script to save you having to enter it in the dialog all the time. + +If you run the script directly, you'll be asked to select a folder of Mobipocket files, and then your PID. The script will attempt to unlock all Mobipocket files in the folder selected, including files in subfolders. + +If you drag and drop files and/or folders onto the script, you will be asked for your PID and then the script will attampt to unlock all the Mobipocket files dragged directly, and all Mobipocket files in the dragged folders (& subfolders). + +If the Python script returns an error, the AppleScript will report it, otherwise it works without any visible feedback. + +The MobiDeDRM.py scripts out there don't work perfectly. If you get the 0.02 version of the script, you can fix up a few problems by apply these changes: + +After line 63: +[tab][tab]bitpos, result = 0,0 + +add in the following two lines: +[tab][tab]if size <= 0: +[tab][tab][tab]return result + +After line 135: +[tab][tab]records, = struct.unpack('>H', sect[0x8:0x8+2]) + +add in the following three lines +[tab][tab]mobi_length, = struct.unpack('>L',sect[0x14:0x18]) +[tab][tab]extra_data_flags = 0 +[tab][tab]if mobi_length >= 0xE4: + +(note that tricky comma after the first instance of mobi_length) + +Add a tab to line 136: +[tab][tab]extra_data_flags, = struct.unpack('>L', sect[0xF0:0xF4]) + +to make it +[tab][tab][tab]extra_data_flags, = struct.unpack('>L', sect[0xF0:0xF4]) + +and change line 165: +print "MobiDeDrm v0.02. Copyright (c) 2008 The Dark Reverser" + +to +print "MobiDeDrm v0.04. Copyright (c) 2008 The Dark Reverser" + +just so that you don't get confused at the command line. + + +Oh -- [tab] just means a single tab character - not the five literal characters [tab]. + + diff --git a/Macintosh_Applications/Mobipocket Unlocker.app/Contents/Info.plist b/Macintosh_Applications/Mobipocket Unlocker.app/Contents/Info.plist new file mode 100644 index 0000000..3b2dedd --- /dev/null +++ b/Macintosh_Applications/Mobipocket 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 4 + CFBundlePackageType + APPL + CFBundleSignature + dplt + LSRequiresCarbon + + WindowState + + name + ScriptWindowState + positionOfDivider + 435 + savedFrame + 53 78 661 691 0 0 1280 778 + selectedTabView + result + + + diff --git a/Macintosh_Applications/Mobipocket Unlocker.app/Contents/MacOS/droplet b/Macintosh_Applications/Mobipocket 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/Mobipocket Unlocker.app/Contents/PkgInfo b/Macintosh_Applications/Mobipocket Unlocker.app/Contents/PkgInfo new file mode 100644 index 0000000..b999e99 --- /dev/null +++ b/Macintosh_Applications/Mobipocket Unlocker.app/Contents/PkgInfo @@ -0,0 +1 @@ +APPLdplt \ No newline at end of file diff --git a/Macintosh_Applications/Mobipocket Unlocker.app/Contents/Resources/MobiDeDRM.py b/Macintosh_Applications/Mobipocket Unlocker.app/Contents/Resources/MobiDeDRM.py new file mode 100644 index 0000000..3f46e77 --- /dev/null +++ b/Macintosh_Applications/Mobipocket Unlocker.app/Contents/Resources/MobiDeDRM.py @@ -0,0 +1,186 @@ +# 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 - Huffdic compressed books were not properly decrypted +# 0.03 - fix 0.02 to work with all Mobipocket eBooks +# 0.04 - Wasn't checking MOBI header length + +import sys,struct,binascii + +class DrmException(Exception): + pass + +#implementation of Pukall Cipher 1 +def PC1(key, src, decryption=True): + sum1 = 0; + sum2 = 0; + keyXorVal = 0; + if len(key)!=16: + print "Bad key length!" + return None + wkey = [] + for i in xrange(8): + wkey.append(ord(key[i*2])<<8 | ord(key[i*2+1])) + + dst = "" + for i in xrange(len(src)): + temp1 = 0; + byteXorVal = 0; + for j in xrange(8): + temp1 ^= wkey[j] + sum2 = (sum2+j)*20021 + sum1 + sum1 = (temp1*346)&0xFFFF + sum2 = (sum2+sum1)&0xFFFF + temp1 = (temp1*20021+1)&0xFFFF + byteXorVal ^= temp1 ^ sum2 + curByte = ord(src[i]) + if not decryption: + keyXorVal = curByte * 257; + curByte = ((curByte ^ (byteXorVal >> 8)) ^ byteXorVal) & 0xFF + if decryption: + keyXorVal = curByte * 257; + for j in xrange(8): + wkey[j] ^= keyXorVal; + dst+=chr(curByte) + return dst + +def checksumPid(s): + letters = "ABCDEFGHIJKLMNPQRSTUVWXYZ123456789" + crc = (~binascii.crc32(s,-1))&0xFFFFFFFF + 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 getSizeOfTrailingDataEntries(ptr, size, flags): + def getSizeOfTrailingDataEntry(ptr, size): + bitpos, result = 0, 0 + if size <= 0: + return result + while True: + v = ord(ptr[size-1]) + result |= (v & 0x7F) << bitpos + bitpos += 7 + size -= 1 + if (v & 0x80) != 0 or (bitpos >= 28) or (size == 0): + return result + num = 0 + flags >>= 1 + while flags: + if flags & 1: + num += getSizeOfTrailingDataEntry(ptr, size - num) + flags >>= 1 + return num + + +class DrmStripper: + def loadSection(self, section): + if (section + 1 == self.num_sections): + endoff = len(self.data_file) + else: + endoff = self.sections[section + 1][0] + off = self.sections[section][0] + return self.data_file[off:endoff] + + def patch(self, off, new): + self.data_file = self.data_file[:off] + new + self.data_file[off+len(new):] + + def patchSection(self, section, new, in_off = 0): + if (section + 1 == self.num_sections): + endoff = len(self.data_file) + else: + endoff = self.sections[section + 1][0] + off = self.sections[section][0] + assert off + in_off + len(new) <= endoff + self.patch(off + in_off, new) + + def parseDRM(self, data, count, pid): + pid = pid.ljust(16,'\0') + keyvec1 = "\x72\x38\x33\xB0\xB4\xF2\xE3\xCA\xDF\x09\x01\xD6\xE2\xE0\x3F\x96" + temp_key = PC1(keyvec1, pid, False) + temp_key_sum = sum(map(ord,temp_key)) & 0xff + found_key = None + for i in xrange(count): + verification, size, type, cksum, cookie = struct.unpack('>LLLBxxx32s', data[i*0x30:i*0x30+0x30]) + cookie = PC1(temp_key, cookie) + ver,flags,finalkey,expiry,expiry2 = struct.unpack('>LL16sLL', cookie) + if verification == ver and cksum == temp_key_sum and (flags & 0x1F) == 1: + found_key = finalkey + break + return found_key + + + def __init__(self, data_file, pid): + + if checksumPid(pid[0:-2]) != pid: + raise DrmException("invalid PID checksum") + pid = pid[0:-2] + + self.data_file = data_file + header = data_file[0:72] + if header[0x3C:0x3C+8] != 'BOOKMOBI': + raise DrmException("invalid file format") + self.num_sections, = struct.unpack('>H', data_file[76:78]) + + self.sections = [] + for i in xrange(self.num_sections): + offset, a1,a2,a3,a4 = struct.unpack('>LBBBB', data_file[78+i*8:78+i*8+8]) + flags, val = a1, a2<<16|a3<<8|a4 + self.sections.append( (offset, flags, val) ) + + sect = self.loadSection(0) + records, = struct.unpack('>H', sect[0x8:0x8+2]) + mobi_length, = struct.unpack('>L',sect[0x14:0x18]) + extra_data_flags = 0 + if mobi_length >= 0xE4: + extra_data_flags, = struct.unpack('>L', sect[0xF0:0xF4]) + + + crypto_type, = struct.unpack('>H', sect[0xC:0xC+2]) + if crypto_type != 2: + raise DrmException("invalid encryption type: %d" % crypto_type) + + # calculate the keys + drm_ptr, drm_count, drm_size, drm_flags = struct.unpack('>LLLL', sect[0xA8:0xA8+16]) + found_key = self.parseDRM(sect[drm_ptr:drm_ptr+drm_size], drm_count, pid) + if not found_key: + raise DrmException("no key found. maybe the PID is incorrect") + + # kill the drm keys + self.patchSection(0, "\0" * drm_size, drm_ptr) + # kill the drm pointers + self.patchSection(0, "\xff" * 4 + "\0" * 12, 0xA8) + # clear the crypto type + self.patchSection(0, "\0" * 2, 0xC) + + # decrypt sections + print "Decrypting. Please wait...", + for i in xrange(1, records+1): + data = self.loadSection(i) + extra_size = getSizeOfTrailingDataEntries(data, len(data), extra_data_flags) + self.patchSection(i, PC1(found_key, data[0:len(data) - extra_size])) + print "done" + def getResult(self): + return self.data_file + +print "MobiDeDrm v0.04. Copyright (c) 2008 The Dark Reverser" +if len(sys.argv)<4: + print "Removes protection from Mobipocket books" + print "Usage:" + print " mobidedrm infile.mobi outfile.mobi PID" +else: + infile = sys.argv[1] + outfile = sys.argv[2] + pid = sys.argv[3] + data_file = file(infile, 'rb').read() + try: + file(outfile, 'wb').write(DrmStripper(data_file, pid).getResult()) + except DrmException, e: + print "Error: %s" % e \ No newline at end of file diff --git a/Macintosh_Applications/Mobipocket Unlocker.app/Contents/Resources/Scripts/main.scpt b/Macintosh_Applications/Mobipocket Unlocker.app/Contents/Resources/Scripts/main.scpt new file mode 100644 index 0000000000000000000000000000000000000000..4a448e3c25ffbf986ac451e9217997a7cc47e225 GIT binary patch literal 15980 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 literal 0 HcmV?d00001 diff --git a/Macintosh_Applications/Mobipocket Unlocker.app/Contents/Resources/Scripts/main.scpt.txt b/Macintosh_Applications/Mobipocket Unlocker.app/Contents/Resources/Scripts/main.scpt.txt new file mode 100644 index 0000000..b67f2f3 --- /dev/null +++ b/Macintosh_Applications/Mobipocket Unlocker.app/Contents/Resources/Scripts/main.scpt.txt @@ -0,0 +1,59 @@ +on unlockfile(encryptedFile, MobiDeDRMPath, 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 \"" & MobiDeDRMPath & "\" \"" & encryptedFilePath & "\" \"" & unlockedFilePath & "\" '" & 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 + if (offset of "Error" in result) > 0 then + with timeout of 5 seconds + display dialog "Can't unlock file " & fileName & ". + +" & result buttons ("OK") default button 1 giving up after 5 + end timeout + end if + end try +end unlockfile + +on unlockfolder(encryptedFolder, MobiDeDRMPath, encryptionKey) + tell application "Finder" to set encryptedFileList to (every file in folder encryptedFolder) whose (name extension is "prc") or (name extension is "mobi") + tell application "Finder" to set encryptedFolderList to (every folder in folder encryptedFolder) + repeat with this_item in encryptedFileList + unlockfile(this_item as text, MobiDeDRMPath, encryptionKey) + end repeat + repeat with this_item in encryptedFolderList + unlockfolder(this_item as text, MobiDeDRMPath, encryptionKey) + end repeat +end unlockfolder + +on run + set MobiDeDRMPath to POSIX path of file ((path to me as text) & "Contents:Resources:MobiDeDRM.py") + set encryptedFolder to choose folder with prompt "Please choose the folder of encrypted Mobipocket files." + set encryptionKey to (display dialog "Enter Mobipocket key for encrypted Mobipocket files." default answer "X12QIL1M3D" buttons {"Cancel", "OK"} default button 2) + set encryptionKey to text returned of encryptionKey + unlockfolder(encryptedFolder, MobiDeDRMPath, encryptionKey) +end run + +on open some_items + set MobiDeDRMPath to POSIX path of file ((path to me as text) & "Contents:Resources:MobiDeDRM.py") + set encryptionKey to (display dialog "Enter Mobipocket key for encrypted Mobipocket files." default answer "X12QIL1M3D" buttons {"Cancel", "OK"} default button 2) + 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, MobiDeDRMPath, encryptionKey) + else + tell application "Finder" to set item_extension to name extension of file this_item + if item_extension is "prc" or item_extension is "mobi" then + unlockfile(this_item as text, MobiDeDRMPath, encryptionKey) + end if + end if + end repeat +end open + diff --git a/Macintosh_Applications/Mobipocket Unlocker.app/Contents/Resources/description.rtfd/TXT.rtf b/Macintosh_Applications/Mobipocket Unlocker.app/Contents/Resources/description.rtfd/TXT.rtf new file mode 100644 index 0000000..19b3535 --- /dev/null +++ b/Macintosh_Applications/Mobipocket 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/Mobipocket Unlocker.app/Contents/Resources/droplet.icns b/Macintosh_Applications/Mobipocket 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/Mobipocket Unlocker.app/Contents/Resources/droplet.rsrc b/Macintosh_Applications/Mobipocket Unlocker.app/Contents/Resources/droplet.rsrc new file mode 100644 index 0000000000000000000000000000000000000000..18bcf1616a3af063a4eff9bfb6ef681bc84cb0dd GIT binary patch literal 362 zcmZQzU}RumU{nDTAnXRjBMnG7;PWvPND?)S=13?p#Dj!nfZ@ehoLpQ5WD6A+6lVZw VIR=LR|A92a5}+z5TW$rA4FD-s450u3 literal 0 HcmV?d00001