Пример #1
0
        public void parseDRM(byte[] byteData, int drmCount, List <byte[]> pidList)
        {
            byte[] keyVec1 = new byte[] { 0x72, 0x38, 0x33, (byte)0xB0, (byte)0xB4, (byte)0xF2, (byte)0xE3, (byte)0xCA, (byte)0xDF, 0x09, 0x01, (byte)0xD6, (byte)0xE2, (byte)0xE0, 0x3F, (byte)0x96 };
            foreach (byte[] pid in pidList)
            {
                byte[] bigpid = new byte[16];
                for (int i = 0; i < 16; i++)
                {
                    bigpid[i] = 0x00;
                }

                for (int i = 0; i < pid.Count(); i++)
                {
                    bigpid[i] = pid[i];
                }
                byte[] tempKey    = PK1Enc(bigpid, keyVec1);
                int    tempKeySum = 0;
                for (int i = 0; i < tempKey.Count(); i++)
                {
                    tempKeySum += tempKey[i];
                }
                tempKeySum = tempKeySum & 0xFF;
                ArraySlice data = new ArraySlice(byteData);
                for (int i = 0; i < drmCount; i++)
                {
                    int    verification = (int)data.getLong(i * 0x30);
                    int    size         = (int)data.getLong(i * 0x30 + 4);
                    int    type         = (int)data.getLong(i * 0x30 + 8);
                    int    chkSum       = (int)data.getByte(i * 0x30 + 12) & 0xFF;
                    byte[] cookie       = data.byteSlice(i * 0x30 + 16, 32);

                    if (chkSum == tempKeySum)
                    {
                        Debug.WriteLine("Cookie: " + bytesToHex(cookie) + " Found at DRMCount: " + i);
                        Debug.WriteLine("Temp Key: " + bytesToHex(tempKey));
                        cookie = PK1Dec(cookie, tempKey, true);
                        Debug.WriteLine("Decrypted Cookie: " + bytesToHex(cookie) + " Found at DRMCount: " + i);
                        ArraySlice slice    = new ArraySlice(cookie);
                        int        ver      = (int)slice.getLong();
                        int        flags    = (int)slice.getLong();
                        int        finalkey = (int)slice.getLong();
                        if (verification == ver && ((flags & 0x1F) > 0))
                        {
                            Debug.WriteLine("W00000T");
                        }
                    }
                }

                Debug.WriteLine("PID: " + Encoding.Default.GetString(pid));
                Debug.WriteLine("HEX BIGPID: " + bytesToHex(bigpid));
                Debug.WriteLine("Key Vec:    " + bytesToHex(keyVec1));
                Debug.WriteLine("Temp Key:   " + bytesToHex(tempKey));
                Debug.WriteLine("Dec Key:    " + bytesToHex(PK1Dec(tempKey, keyVec1, false)));
                Debug.WriteLine("\n\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);
        }
Пример #3
0
 public Section(ArraySlice slice)
 {
     offset = slice.getLong();
     flags  = slice.getByte();
     val    = (slice.getByte() << 16) | (slice.getByte() << 8) | (slice.getByte());
 }
Пример #4
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);
        }