Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- @ECHO OFF
- REM ============================================================================ FIRSTRUN
- CLS
- ECHO.
- ECHO DEKDRM.BAT ^(by Kobostaya^) is a Windows batch script to remove Kobo's
- ECHO proprietary DRM ^(kdrm^) from their kepub format ebooks. It can free your Kobo
- ECHO ebooks that are not available for download as regular epubs with Adobe DRM.
- ECHO.
- ECHO ^|======================================================================
- ECHO ^| USAGE: DEKDRM [path]00000000-0000-0000-0000-000000000000[.ext] [...]
- ECHO ^|======================================================================
- ECHO ^| Output file location: [path]00000000-0000-0000-0000-000000000000.epub
- ECHO ^|======================================================================
- ECHO.
- ECHO 00000000-0000-0000-0000-000000000000 is the name of a kepub file with DRM.
- ECHO.
- ECHO The script will put the DRM-free version in the same folder the original file
- ECHO is in, named as .epub added to the original name.
- ECHO.
- ECHO You can pass more than one file at a time ^(but not folder names^).
- ECHO.
- ECHO Already DRM-free files are automatically skipped.
- ECHO.
- PAUSE
- CLS
- ECHO.
- ECHO If you don't want to log processing messages, it's probably easiest to
- ECHO simply drag files from your Kobo kepub folder onto this .BAT file.
- ECHO Dragging many files in one go is supported as well, but can obviously take
- ECHO a while to process.
- ECHO.
- ECHO IMPORTANT!
- ECHO If the kepub file's name has been changed from its original GUID-style name,
- ECHO this script ^(specifically the second database lookup^) will fail, as the GUID
- ECHO is needed to determine the encrypted files inside the kepub and their
- ECHO decryption keys. Kepub files can have extensions though, these will simply be
- ECHO ignored in the processing.
- ECHO.
- PAUSE
- CLS
- ECHO REQUIREMENTS:
- ECHO 1. Windows XP.
- ECHO ^(Tested on Windows XP Pro SP3.^)
- ECHO Vista, Win7 and Win8 should work with no or minimal changes but the point is
- ECHO THEY HAVEN'T BEEN TESTED so DO NOT try the script on them "as is" unless
- ECHO you're positive you know what you're doing!
- ECHO 2. Kobo Desktop Edition for PC.
- ECHO World: http://download.kobobooks.com/desktop/kobodesktop/kobosetup.exe
- ECHO Japanese: http://download.kobobooks.com/desktop/RakutenBooks/KoboSetup.exe
- ECHO ^(Tested with 3.2.3.0 of both.^)
- ECHO 3. A command-line zip archiver of your choice.
- ECHO ^(Tested with 7-Zip 9.20 from http://www.7-zip.org/^)
- ECHO === You MUST adjust all ZIPCMD calls if using a different zip program!
- ECHO 4. SQLite command-line shell.
- ECHO http://www.sqlite.org/download.html
- ECHO ^(Tested with 3.7.17.^)
- ECHO 5. OpenSSL command-line.
- ECHO http://gnuwin32.sourceforge.net/packages/openssl.htm
- ECHO ^(Tested with 0.9.8h from GNUWin32 and 1.0.1b from a Perl distro.^)
- ECHO 6. Hexdump.
- ECHO http://gnuwin32.sourceforge.net/packages/util-linux-ng.htm
- ECHO ^(Tested with util-linux-ng 2.14.1.^)
- ECHO.
- PAUSE
- CLS
- ECHO.
- ECHO.
- ECHO.
- ECHO ^|==============================================================================
- ECHO ^|
- ECHO ^| WARNING!
- ECHO ^|
- ECHO ^| If you execute this script, you agree to do so ENTIRELY AT YOUR OWN RISK.
- ECHO ^| ABSOLUTELY NO GUARANTEES are given as to the results.
- ECHO ^| Input sanity checks are NOT EXHAUSTIVE and DATA LOSS IS POSSIBLE.
- ECHO ^|
- ECHO ^|==============================================================================
- ECHO.
- ECHO.
- ECHO Comment out the FIRSTRUN section of the script to use it for real.
- ECHO.
- ECHO.
- ECHO Also, feel free to create a more portable and user-friendly version of this.
- ECHO I've already spent enough time digging out the information needed to get this
- ECHO to work and it "works for me", so I'm not going to do any more work on this.
- ECHO.
- GOTO :EOF
- REM ============================================================================= FIRSTRUN
- SETLOCAL ENABLEEXTENSIONS
- REM |=======================================
- REM |
- REM | Check the prerequisites.
- REM |
- REM |=======================================
- REM ===================================================================== OSCHECK
- VER | FIND "Microsoft Windows XP [Version 5.1.2600]" >NUL
- IF %ERRORLEVEL%==1 (
- CLS
- ECHO.
- ECHO ^|======================================================================
- ECHO ^|
- ECHO ^| This script has only been tested on Windows XP.
- ECHO ^|
- ECHO ^| To run it on a different Windows version, comment out the OSCHECK
- ECHO ^| section of the script.
- ECHO ^|
- ECHO ^| SOMETHING COULD GO WRONG, better be sure you know what you're doing!
- ECHO ^|
- ECHO ^|======================================================================
- ECHO.
- GOTO :EOF
- )
- REM ===================================================================== OSCHECK
- IF [%1] == [] (
- ECHO.
- ECHO ^|======================================================================
- ECHO ^| USAGE: DEKDRM [path]00000000-0000-0000-0000-000000000000[.ext] [...]
- ECHO ^|======================================================================
- ECHO ^| Output file location: [path]00000000-0000-0000-0000-000000000000.epub
- ECHO ^|======================================================================
- ECHO.
- GOTO :EOF
- )
- REM The prefix used for device ID generation.
- SET PREFIX=NoCanLook
- REM PREFIX is CaSe SeNsItIvE!
- REM The wording seems to hint that on an actual Kobo device Nickel would use either the
- REM device serial number or serial+MAC, something not available on a PC. Pardon me for
- REM not finding out for sure, it's a pain to trace code that doesn't get executed.
- REM The MAC address used for device ID generation.
- SET MACADDR=00:00:00:00:00:00
- REM MACADDR is CaSe SeNsItIvE, with UPPERCASE hex!
- REM Be sure to use colons and not dashes like in ipconfig display.
- IF %MACADDR%==00:00:00:00:00:00 (
- ECHO.
- ECHO You need to edit MACADDR in this script with your network card MAC address.
- ECHO Use "ipconfig /all" to see your MAC address^(es^) ^("Physical Address"^).
- ECHO If there is more than one, try them all until you find the one that works.
- GOTO :EOF
- )
- REM Nickel first tries to get a cached MAC from /tmp/.mac-address and then /.mac-address,
- REM after which it queries all network interfaces and takes the MAC of the first non-loopback
- REM interface it sees.
- REM Which means that on the PC it may easily end up with a VPN or VM interface instead of the
- REM real network card. So if you uninstalled your VPN, you'd lose access to your DRM-ed
- REM kepubs that are on that PC. At least until you can resync/redownload, provided all the
- REM books are still available.
- REM Works under WinXP, adjust for others.
- REM Be sure to use double quotes if the the path contains spaces.
- SET KOBODB="%USERPROFILE%\Local Settings\Application Data\Kobo\Kobo Desktop Edition\Kobo.sqlite"
- IF NOT EXIST %KOBODB% (
- ECHO.
- ECHO Kobo database not found at %KOBODB%.
- ECHO.
- ECHO Find Kobo.sqlite on your computer and edit KOBODB in this script.
- GOTO :EOF
- )
- REM These will most likely need adjusting on your system.
- REM If using another archiver, be sure to adjust all ZIPCMD switches below.
- SET ZIPCMD="C:\Program Files\7-zip\7z.exe"
- SET SQLITECMD=sqlite3.exe
- SET OPENSSLCMD=openssl.exe
- SET HEXDUMPCMD=hexdump.exe
- %ZIPCMD% >NUL 2>&1
- IF %ERRORLEVEL%==3 GOTO BADZIP
- IF %ERRORLEVEL%==9009 GOTO BADZIP
- ECHO.
- ECHO Using Zip: %ZIPCMD%
- %ZIPCMD% | FIND /I "copyright (c)"
- GOTO GOODZIP
- :BADZIP
- ECHO.
- ECHO Zip program not found: %ZIPCMD%.
- ECHO.
- ECHO Check your PATH and/or edit ZIPCMD in this script.
- GOTO :EOF
- :GOODZIP
- %SQLITECMD% -version >NUL 2>&1
- IF %ERRORLEVEL%==3 GOTO BADSQLITE
- IF %ERRORLEVEL%==9009 GOTO BADSQLITE
- ECHO.
- ECHO Using SQLite: %SQLITECMD%
- %SQLITECMD% -version
- GOTO GOODSQLITE
- :BADSQLITE
- ECHO.
- ECHO SQLite program not found: %SQLITECMD%.
- ECHO.
- ECHO Check your PATH and/or edit SQLITECMD in this script.
- GOTO :EOF
- :GOODSQLITE
- %OPENSSLCMD% version >NUL 2>&1
- IF %ERRORLEVEL%==3 GOTO BADOPENSSL
- IF %ERRORLEVEL%==9009 GOTO BADOPENSSL
- ECHO.
- ECHO Using OpenSSL: %OPENSSLCMD%
- %OPENSSLCMD% version 2>NUL
- GOTO GOODOPENSSL
- :BADOPENSSL
- ECHO.
- ECHO OpenSSL program not found: %OPENSSLCMD%.
- ECHO.
- ECHO Check your PATH and/or edit OPENSSLCMD in this script.
- GOTO :EOF
- :GOODOPENSSL
- %HEXDUMPCMD% <NUL >NUL 2>&1
- IF %ERRORLEVEL%==3 GOTO BADHEXDUMP
- IF %ERRORLEVEL%==9009 GOTO BADHEXDUMP
- ECHO.
- ECHO Using Hexdump: %HEXDUMPCMD%
- GOTO GOODHEXDUMP
- :BADHEXDUMP
- ECHO.
- ECHO Hexdump program not found: %HEXDUMPCMD%.
- ECHO.
- ECHO Check your PATH and/or edit HEXDUMPCMD in this script.
- GOTO :EOF
- :GOODHEXDUMP
- REM |===========================================
- REM |
- REM | Calculate the global kepub decryption key.
- REM |
- REM |===========================================
- SETLOCAL ENABLEDELAYEDEXPANSION
- ECHO.
- ECHO -------------------------------------------------------------------------------
- ECHO.
- ECHO MAC address: %MACADDR%.
- ECHO.
- ECHO Hashing "%PREFIX%%MACADDR%" for DeviceID.
- REM Calculate the deviceID SHA-256 digest.
- REM Really "nice" syntax to set a variable from command output without a temp file...
- REM ECHO | SET /P is needed to avoid a newline, as openssl must get only the string.
- REM Openssl errors are flushed because it tends to throw useless warnings about
- REM a missing config file. Remove the 2> redirects if you need to debug the script.
- FOR /F "tokens=* delims=" %%I IN ('ECHO ^| SET /P dummyName^="%PREFIX%%MACADDR%" ^| %OPENSSLCMD% dgst -sha256 2^>NUL') DO (
- SET DEVID=%%I
- REM Newer openssl versions include "(stdin)= " in their output but older ones don't,
- REM so we need to strip it if it's there.
- SET DEVID=!DEVID:* =!
- )
- REM DEVID is CaSe SeNsItIvE, with lowercase hex!
- ECHO DeviceID: %DEVID%.
- ECHO.
- ECHO Kobo database: %KOBODB%.
- REM Get the userID from database
- FOR /F "usebackq delims=" %%I IN (`%SQLITECMD% %KOBODB% "select UserID from user;"`) DO SET USERID=%%I
- REM USERID is CaSe SeNsItIvE, with lowercase hex!
- ECHO.
- ECHO UserID: %USERID%.
- ECHO.
- ECHO Hashing "%DEVID%%USERID%" ^(DeviceID+UserID^) for kepub key.
- REM Calculate the deviceID+userID SHA-256 digest.
- REM Really "nice" syntax to set a variable from command output without a temp file...
- REM ECHO | SET /P is needed to avoid a newline, as openssl must get only the string.
- FOR /F "tokens=* delims=" %%I IN ('ECHO ^| SET /P dummyName^="%DEVID%%USERID%" ^| %OPENSSLCMD% dgst -sha256 2^>NUL') DO (
- SET KEPUBKEY=%%I
- REM Newer openssl versions include "(stdin)= " in their output but older ones don't,
- REM so we need to strip it if it's there.
- SET KEPUBKEY=!KEPUBKEY:* =!
- ECHO Hash: !KEPUBKEY!.
- ECHO ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- REM The actual decryption key is only the tail-end 128 bits of the digest.
- SET KEPUBKEY=!KEPUBKEY:~32,32!
- )
- REM KEPUBKEY is not case sensitive.
- ECHO Kepub key: %KEPUBKEY%.
- REM Pass KEPUBKEY out.
- ENDLOCAL & SET KEPUBKEY=%KEPUBKEY%
- :PROCESS
- ECHO.
- ECHO -------------------------------------------------------------------------------
- REM |=============================================================================
- REM |
- REM | A few sanity checks to make reasonably sure we can work with our input.
- REM |
- REM |=============================================================================
- IF NOT EXIST %1 (
- ECHO.
- ECHO File not found: %~f1.
- GOTO :NEXTFILE
- )
- REM Check for folder attribute.
- ECHO %~a1 | FIND /I "d" >NUL
- IF %ERRORLEVEL%==0 (
- ECHO.
- ECHO %~f1 is a folder, this script only works on files.
- GOTO :NEXTFILE
- )
- ECHO.
- ECHO Removing DRM from file %~f1.
- %ZIPCMD% l -tzip %1 mimetype | FIND /I "mimetype" >NUL
- IF %ERRORLEVEL%==1 (
- ECHO.
- ECHO This file does not seem to be an ebook.
- GOTO :NEXTFILE
- )
- %ZIPCMD% l -tzip %1 -r rights.xml | FIND /I "rights.xml" >NUL
- IF %ERRORLEVEL%==1 (
- ECHO.
- ECHO This ebook does not seem to have DRM ^(no rights.xml^).
- GOTO :NEXTFILE
- )
- REM |=======================================
- REM |
- REM | Kepub file DRM removal starts here.
- REM |
- REM |=======================================
- ECHO.
- ECHO Setting up and unpacking.
- REM Drive and path of the input file.
- SET INFILEDIR=%~dp1
- REM Name of the input file.
- SET INFILENAME=%~n1
- SET WORKDIR=%TEMP%\%RANDOM%%RANDOM%%RANDOM%%RANDOM%%RANDOM%
- MKDIR %WORKDIR%
- REM Expand the EPUB archive.
- %ZIPCMD% x -tzip -o%WORKDIR% %1 * >NUL
- PUSHD %WORKDIR%
- REM Get the encrypted decryption keys for individual encrypted files from Kobo database.
- REM Keys in the database are Base64 encoded.
- %SQLITECMD% %KOBODB% -separator "," "select elementKey,elementId from content_keys where volumeid = '%INFILENAME%';" > keys.tmp
- SETLOCAL ENABLEDELAYEDEXPANSION
- FOR /F "tokens=1,2 delims=," %%I IN (keys.tmp) DO (
- REM Switching to better named variables for clarity.
- SET ENCFILEKEY=%%I
- SET FILENAME=%%J
- ECHO.
- ECHO Decrypting key "!ENCFILEKEY!" for !FILENAME!.
- REM Both the decryption keys and the files are encrypted with AES-128 ECB.
- REM Need to Base64 decode the keys before decrypting them (-a).
- REM For opensll's pleasure, for that to work, the Base64 string must end with a newline.
- REM Use no padding (-nopad) when decrypting the keys.
- REM IV is not really useful here, but older openssl will fail without it.
- REM Decrypting these keys will result in their binary form, so we have
- REM to use a temp file here because piping binary is problematic.
- ECHO !ENCFILEKEY! | %OPENSSLCMD% enc -d -aes-128-ecb -iv 00000000000000000000000000000000 -K %KEPUBKEY% -a -nopad -out bin.tmp 2>NUL
- REM Turn binary keys into hex for command-line usage. Case is unimportant here.
- FOR /F "delims=" %%K IN ('%HEXDUMPCMD% -e "16/1 ""%%02x""" bin.tmp') DO (
- SET DECFILEKEY=%%K
- REM And we decrypt the files with the decrypted keys.
- ECHO Key: !DECFILEKEY!.
- ECHO Decrypting !FILENAME!.
- %OPENSSLCMD% enc -d -aes-128-ecb -iv 00000000000000000000000000000000 -K !DECFILEKEY! -in !FILENAME! -out !FILENAME!.new 2>NUL
- SET NAMEWITHPATH=!FILENAME!
- REM Need to turn slashes into backslashes for Windows commands.
- SET NAMEWITHPATH=!NAMEWITHPATH:/=\!
- REM Strip down to filename only for REN syntax.
- FOR %%N IN ("!NAMEWITHPATH!") DO SET NAMEONLY=%%~nxN
- REM Replace encrypted files with decrypted ones.
- DEL /F /Q !NAMEWITHPATH!
- REN !NAMEWITHPATH!.new !NAMEONLY!
- )
- )
- ENDLOCAL
- ECHO.
- ECHO Repacking and cleaning up.
- REM Off with the garbage before repacking.
- DEL /Q rights.xml
- DEL /Q *.tmp
- REM Store mimetype first and then add the rest compressed.
- %ZIPCMD% a -tzip %INFILENAME%.epub mimetype -mx0 >NUL
- %ZIPCMD% a -tzip %INFILENAME%.epub * -r -x!mimetype -x!%INFILENAME%.epub >NUL
- :end
- POPD
- REM Put the DRM-free version in the same directory the DRM'ed one is in.
- MOVE %WORKDIR%\%INFILENAME%.epub "%INFILEDIR%"
- REM Clean up.
- RMDIR /S /Q %WORKDIR%
- ECHO.
- ECHO DRM-free version is at %INFILEDIR%%INFILENAME%.epub.
- REM Any more files to process?
- :NEXTFILE
- SHIFT
- IF [%1]==[] GOTO :EOF
- GOTO :PROCESS
Add Comment
Please, Sign In to add comment