Exemplo n.º 1
0
        public void processBook(List <byte[]> pidList)
        {
            int firstOffset = (int)mSections.ElementAt(0).offset;
            int cryptoType  = mEncMobiBook.getShort(firstOffset + 0xC);

            if (cryptoType == 0)
            {
                Debug.WriteLine("This Book is not encrypted");
            }
            else if (cryptoType != 1 && cryptoType != 2)
            {
                throw new Exception("Unknown Mobipocket CryptoType: " + cryptoType);
            }

            if (mMetaMap.ContainsKey(406))
            {
                byte[] data406 = mMetaMap[406];
                if ((new ArraySlice(data406)).getLongLong() != 0)
                {
                    throw new Exception("Cannot Decode library or rented eBooks");
                }
            }

            List <byte[]> goodPids = validatePins(pidList);

            byte[] pid = { 0, 0, 0, 0, 0, 0, 0, 0 };
            byte[] foundKey;
            if (cryptoType == 1)
            {
                byte[]  t1KeyVec = Encoding.Default.GetBytes("QDCVEPMU675RUBSZ");
                byte [] bookKeyData;

                if (mHeader.getMagicString().Equals(MobiHeader.TEXT_READ))
                {
                    bookKeyData = mEncMobiBook.byteSlice(0x0E + firstOffset, 16);
                }
                else if (mMobiVersion < 0)
                {
                    bookKeyData = mEncMobiBook.byteSlice(0x90 + firstOffset, 16);
                }
                else
                {
                    bookKeyData = mEncMobiBook.byteSlice(mMobiLength + firstOffset + 16, 16);
                }

                foundKey = PK1Dec(bookKeyData, t1KeyVec, false);
            }
            else
            {
                int drmPointer = (int)mEncMobiBook.getLong(firstOffset + 0xA8);
                int drmCount   = (int)mEncMobiBook.getLong();
                int drmSize    = (int)mEncMobiBook.getLong();
                int drmFlags   = (int)mEncMobiBook.getLong();
                parseDRM(mEncMobiBook.byteSlice(drmPointer + firstOffset, drmSize), drmCount, goodPids);
            }
        }
Exemplo n.º 2
0
        public MobiHeader(ArraySlice headerSlice)
        {
            mMagic = System.Text.Encoding.Default.GetString(headerSlice.byteSlice(0x3C, 8));
            if (!mMagic.Equals(BOOK_MOBI) && !mMagic.Equals(TEXT_READ))
            {
                throw new Exception("Invalid File Format");
            }

            mNumSections = headerSlice.getShort(76);
        }
Exemplo n.º 3
0
        public MobiBook(String filename)
        {
            mEncMobiBook = getBookSlice(filename);
            mHeader      = new MobiHeader(mEncMobiBook);
            mEncMobiBook.seek(MobiHeader.HEADER_SIZE);

            for (int i = 0; i < mHeader.getNumberSections(); i++)
            {
                mSections.Add(new Section(mEncMobiBook));
            }

            int offset = (int)mSections[0].offset;

            mCompression = mEncMobiBook.getShort(offset);
            mRecords     = mEncMobiBook.getShort(offset + 0x8);

            if (mHeader.getMagicString().Equals(MobiHeader.TEXT_READ))
            {
                mExtraDataFlags = 0;
                mMobiLength     = 0;
                mMobiCodepage   = 0;
                mMobiVersion    = -1;
                return;
            }

            mMobiLength   = (int)mEncMobiBook.getLong(offset + 0x14);
            mMobiCodepage = (int)mEncMobiBook.getLong(offset + 0x1c);
            mMobiVersion  = (int)mEncMobiBook.getLong(offset + 0x68);

            if ((mMobiLength >= 0xE4) && (mMobiVersion >= 5))
            {
                mExtraDataFlags = mEncMobiBook.getShort(offset + 0xF2);
            }

            if (mCompression != 17480)
            {
                // multibyte utf8 data is included in the encryption for PalmDoc compression
                // so clear that byte so that we leave it to be decrypted.
                mExtraDataFlags &= 0xFFFE;
            }


            //if exth region exists parse it for metadata array
            int exthFlag   = (int)mEncMobiBook.getLong(offset + 0x80);
            int exthOffset = 16 + mMobiLength;

            if ((exthFlag & 0x40) > 0)
            {
                if ((exthOffset + mEncMobiBook.size() >= 4) && System.Text.Encoding.Default.GetString(mEncMobiBook.byteSlice(exthOffset + offset, 4)).Equals("EXTH"))
                {
                    int nItems = (int)mEncMobiBook.getLong(exthOffset + offset + 8);
                    int pos    = offset + exthOffset + 12;
                    for (int i = 0; i < nItems - 1; i++)
                    {
                        int type = (int)mEncMobiBook.getLong(pos);
                        int size = (int)mEncMobiBook.getLong(pos + 4);
                        mMetaMap[type] = mEncMobiBook.byteSlice(pos + 8, size - 8);

                        /* TODO:
                         # reset the text to speech flag and clipping limit, if present
                         # if type == 401 and size == 9:
                         # set clipping limit to 100%
                         #    self.patchSection(0, "\144", 16 + self.mobi_length + pos + 8)
                         # elif type == 404 and size == 9:
                         # make sure text to speech is enabled
                         #    self.patchSection(0, "\0", 16 + self.mobi_length + pos + 8)
                         */
                        pos += size;
                    }
                }
            }

            Debug.WriteLine(mHeader);
            Debug.WriteLine("BookTitle: {0} \nMobiLength: {1} \nMobiCodePage {2}\nExtraDataFlags: {3} \nMobiVersion: {4}\n", getBookTitle(), mMobiLength, mMobiCodepage, mExtraDataFlags, mMobiVersion);
            List <byte[]> pidList = new List <byte[]>();

            pidList.Add(Encoding.Default.GetBytes("DL3pB54YXE"));
            pidList.Add(Encoding.Default.GetBytes("DL3pB54Y"));
            pidList.Add(Encoding.Default.GetBytes("SSEVC1U7"));
            processBook(pidList);
        }