Beispiel #1
0
        private EReaderProcessor(Pdb pdb, string name, string ccNumber)
        {
            if (!(pdb.Filetype == "PNRd" && pdb.Creator == "PPrs"))
            {
                throw new FormatException("Invalid eReader file.");
            }

            pdbReader = pdb;
            var eReaderPdb = new EReaderPdb(pdbReader);

            if (!eReaderPdb.HaveDrm)
            {
                throw new InvalidOperationException("File doesn't have DRM or have unknown DRM version: {0}!");
            }

            if (!(eReaderPdb.CompressionMethod == EReaderCompression.Drm1 || eReaderPdb.CompressionMethod == EReaderCompression.Drm2))
            {
                throw new InvalidOperationException($"Unsupported compression method or DRM version: {eReaderPdb.CompressionMethod}!");
            }

            data = pdbReader.GetSection(1);
            var desEngine     = GetDesEngine(data.Copy(0, 8));
            var decryptedData = desEngine.TransformFinalBlock(data.Copy(-8), 0, 8);
            var cookieShuf    = decryptedData[0] << 24 | decryptedData[1] << 16 | decryptedData[2] << 8 | decryptedData[3];
            var cookieSize    = decryptedData[4] << 24 | decryptedData[5] << 16 | decryptedData[6] << 8 | decryptedData[7];

            if (cookieShuf < 0x03 || cookieShuf > 0x14 || cookieSize < 0xf0 || cookieSize > 0x200)
            {
                throw new InvalidOperationException("Unsupportd eReader format");
            }

            var input = desEngine.TransformFinalBlock(data.Copy(-cookieSize), 0, cookieSize);
            var r     = UnshuffleData(input.SubRange(0, -8), cookieShuf);
            //using (var stream = new FileStream(pdb.Filename+".eReaderSection1Dump", FileMode.Create, FileAccess.ReadWrite, FileShare.Read)) stream.Write(r, 0, r.Length);
            var  userKeyPart1 = Encoding.ASCII.GetBytes(FixUserName(name));
            var  userKeyPart2 = Encoding.ASCII.GetBytes(ccNumber.ToCharArray().Copy(-8));
            long userKey;

            using (var stream1 = new MemoryStream(userKeyPart1))
                using (var stream2 = new MemoryStream(userKeyPart2))
                {
                    userKey = new CRC32().GetCrc32(stream1) & 0xffffffff;
                    userKey = userKey << 32 | new CRC32().GetCrc32(stream2) & 0xffffffff;
                }
            var drmSubVersion = (ushort)(r[0] << 8 | r[1]);

            numTextPages   = (ushort)(r[2] << 8 | r[3]) - 1;
            flags          = r[4] << 24 | r[5] << 16 | r[6] << 8 | r[7];
            firstImagePage = (ushort)(r[24] << 8 | r[25]);
            numImagePages  = (ushort)(r[26] << 8 | r[27]);
            if ((flags & ReqdFlags) != ReqdFlags)
            {
                throw new InvalidOperationException($"Unsupported flags combination: {flags:x8}");
            }

            var userKeyArray = BitConverter.GetBytes(userKey);

            if (BitConverter.IsLittleEndian)
            {
                userKeyArray = userKeyArray.Reverse();
            }
            desEngine = GetDesEngine(userKeyArray);
            var encryptedKey    = new byte[0];
            var encryptedKeySha = new byte[0];

            if (eReaderPdb.CompressionMethod == EReaderCompression.Drm1)
            {
                if (drmSubVersion != 13)
                {
                    throw new InvalidOperationException($"Unknown eReader DRM subversion ID: {drmSubVersion}");
                }

                encryptedKey    = r.Copy(44, 8);
                encryptedKeySha = r.Copy(52, 20);
            }
            else if (eReaderPdb.CompressionMethod == EReaderCompression.Drm2)
            {
                encryptedKey    = r.Copy(172, 8);
                encryptedKeySha = r.Copy(56, 20);
            }
            contentKey = desEngine.TransformFinalBlock(encryptedKey, 0, encryptedKey.Length);
            byte[] checkHash;
            using (var sha1 = SHA1.Create())
                checkHash = sha1.ComputeHash(contentKey);
            if (!encryptedKeySha.SequenceEqual(checkHash))
            {
                var s = new StringBuilder();
                for (var x = 0; x < r.Length - 8; x += 2)
                {
                    for (var y = 0; y < (x - 20); y += 2)
                    {
                        if (TestKeyDecryption(desEngine, r, x, y))
                        {
                            s.AppendFormat("keyOffset={0}, hashOffset={1}\n", x, y);
                        }
                    }
                    for (var y = x + 8; y < (r.Length - 20); y += 2)
                    {
                        if (TestKeyDecryption(desEngine, r, x, y))
                        {
                            s.AppendFormat("keyOffset={0}, hashOffset={1}\n", x, y);
                        }
                    }
                }
                if (s.Length > 0)
                {
                    throw new InvalidDataException("Key and/or KeyHash offset mismatch. Possible values:\n\n" + s);
                }
                throw new ArgumentException("Incorrect Name of Credit Card number.");
            }
            contentDecryptor = GetDesEngine(contentKey);
        }
Beispiel #2
0
        private EReaderProcessor(Pdb pdb, string name, string ccNumber)
        {
            if (!(pdb.Filetype == "PNRd" && pdb.Creator == "PPrs")) throw new FormatException("Invalid eReader file.");
            pdbReader = pdb;
            var eReaderPdb = new EReaderPdb(pdbReader);
            if (!eReaderPdb.HaveDrm)
                throw new InvalidOperationException("File doesn't have DRM or have unknown DRM version: {0}!");
            if (!(eReaderPdb.CompressionMethod == EReaderCompression.Drm1 || eReaderPdb.CompressionMethod == EReaderCompression.Drm2))
                throw new InvalidOperationException(string.Format("Unsupported compression method or DRM version: {0}!", eReaderPdb.CompressionMethod));

            data = pdbReader.GetSection(1);
            ICryptoTransform desEngine = GetDesEngine(data.Copy(0, 8));
            byte[] decryptedData = desEngine.TransformFinalBlock(data.Copy(-8), 0, 8);
            int cookieShuf = decryptedData[0] << 24 | decryptedData[1] << 16 | decryptedData[2] << 8 | decryptedData[3];
            int cookieSize = decryptedData[4] << 24 | decryptedData[5] << 16 | decryptedData[6] << 8 | decryptedData[7];
            if (cookieShuf < 0x03 || cookieShuf > 0x14 || cookieSize < 0xf0 || cookieSize > 0x200) throw new InvalidOperationException("Unsupportd eReader format");
            byte[] input = desEngine.TransformFinalBlock(data.Copy(-cookieSize), 0, cookieSize);
            byte[] r = UnshuffData(input.SubRange(0, -8), cookieShuf);
            //using (var stream = new FileStream(pdb.Filename+".eReaderSection1Dump", FileMode.Create, FileAccess.ReadWrite, FileShare.Read)) stream.Write(r, 0, r.Length);
            byte[] userKeyPart1 = Encoding.ASCII.GetBytes(FixUserName(name));
            byte[] userKeyPart2 = Encoding.ASCII.GetBytes(ccNumber.ToCharArray().Copy(-8));
            long userKey;
            using (var stream1 = new MemoryStream(userKeyPart1))
            using (var stream2 = new MemoryStream(userKeyPart2))
            {
                userKey = new CRC32().GetCrc32(stream1) & 0xffffffff;
                userKey = userKey << 32 | new CRC32().GetCrc32(stream2) & 0xffffffff;
            }
            var drmSubVersion = (ushort)(r[0] << 8 | r[1]);
            numTextPages = (ushort)(r[2] << 8 | r[3]) - 1;
            flags = r[4] << 24 | r[5] << 16 | r[6] << 8 | r[7];
            firstImagePage = (ushort)(r[24] << 8 | r[25]);
            numImagePages = (ushort)(r[26] << 8 | r[27]);
            if ((flags & ReqdFlags) != ReqdFlags) throw new InvalidOperationException(string.Format("Unsupported flags combination: {0:x8}", flags));
            byte[] userKeyArray = BitConverter.GetBytes(userKey);
            if (BitConverter.IsLittleEndian) userKeyArray = userKeyArray.Reverse();
            desEngine = GetDesEngine(userKeyArray);
            byte[] encryptedKey = new byte[0],
                   encryptedKeySha = new byte[0];
            if (eReaderPdb.CompressionMethod == EReaderCompression.Drm1)
            {
                if (drmSubVersion != 13) throw new InvalidOperationException(string.Format("Unknown eReader DRM subversion ID: {0}", drmSubVersion));
                encryptedKey = r.Copy(44, 8);
                encryptedKeySha = r.Copy(52, 20);
            }
            else if (eReaderPdb.CompressionMethod == EReaderCompression.Drm2)
            {
                encryptedKey = r.Copy(172, 8);
                encryptedKeySha = r.Copy(56, 20);
            }
            contentKey = desEngine.TransformFinalBlock(encryptedKey, 0, encryptedKey.Length);
            byte[] checkHash = SHA1.Create().ComputeHash(contentKey);
            if (!encryptedKeySha.IsEqualTo(checkHash))
            {
                var s = new StringBuilder();
                for (var x = 0; x < (r.Length - 8); x += 2)
                {
                    for (var y = 0; y < (x - 20); y += 2) if (TestKeyDecryption(desEngine, r, x, y)) s.AppendFormat("keyOffset={0}, hashOffset={1}\n", x, y);
                    for (var y = x + 8; y < (r.Length - 20); y += 2) if (TestKeyDecryption(desEngine, r, x, y)) s.AppendFormat("keyOffset={0}, hashOffset={1}\n", x, y);
                }
                if (s.Length > 0) throw new InvalidDataException("Key and/or KeyHash offset mismatch. Possible values:\n\n" + s);
                throw new ArgumentException("Incorrect Name of Credit Card number.");
            }
            contentDecryptor = GetDesEngine(contentKey);
        }