Exemplo n.º 1
0
        /// <summary>
        /// Adds a complete stream to the hash data.
        /// </summary>
        /// <param name="hashBuf">Current data to hash</param>
        /// <param name="streamName">Stream to hash</param>
        /// <param name="stg">Storage of the stream</param>
        private void AddStream(ICollection<byte[]> hashBuf, string streamName, CFStorage stg)
        {
            try {
                var stream = stg.GetStream(streamName);
                if (stream != null) {
                    var data = stream.GetData();
                    hashBuf.Add(data);
                }
            } catch (CFItemNotFound) {
                _logger.Warn("Skipping non-existent Stream {0}.", streamName);

            } catch (Exception e) {
                _logger.Error(e, "Error reading data!");
                _crashManager.Report(e, "vpt");
            }
        }
Exemplo n.º 2
0
 /// <summary>
 /// Reads the stored checksum from the table's `GameStg` storage.
 /// </summary>
 /// <param name="storage">`GameStg` of the table</param>
 /// <returns>Checksum</returns>
 private static byte[] ReadChecksum(CFStorage storage)
 {
     return storage.GetStream("MAC").GetData();
 }
Exemplo n.º 3
0
        /// <summary>
        /// Adds the data of all BIFF blocks to the hash data.
        /// </summary>
        /// <param name="hashBuf">Current data to hash</param>
        /// <param name="streamName">Name of the stream where BIFF data is stored</param>
        /// <param name="stg">Storage of the stream</param>
        /// <param name="offset">Byte offset to start reading BIFF data</param>
        /// <param name="stats">Stats collector</param>
        /// <returns>List of parsed BIFF blocks</returns>
        private List<BiffBlock> AddBiffData(ICollection<byte[]> hashBuf, string streamName, CFStorage stg, int offset, TableStats stats)
        {
            // init result
            var blocks = new List<BiffBlock>();

            // get stream from compound document
            var stream = stg.GetStream(streamName);
            if (stream == null) {
                _logger.Warn("No stream {0} in provided storage!", streamName);
                return blocks;
            }

            // get data from stream
            byte[] buf;
            try {
                buf = stream.GetData();
            } catch (CFItemNotFound) {
                _logger.Warn("No data in stream {0}.", streamName);
                return blocks;
            }

            // loop through BIFF blocks
            var i = offset;
            do {
                // Usually, we have:
                //
                //   [4 bytes] size of block              | `blockSize` - not hashed
                //   [blockSize bytes] data, which is:    | `block`     - hashed
                //       [4 bytes] tag name               | `tag`
                //       [blockSize - 4 bytes] real data  | `data`
                //
                // In case of a string, real data is again prefixed with 4 bytes
                // of string size, but we don't care because those are hashed too.
                //
                // What's NOT hashed is the original block size or the stream block
                // size, see below.
                //
                var blockSize = BitConverter.ToInt32(buf, i);
                var block = buf.Skip(i + 4).Take(blockSize).ToArray(); // contains tag and data
                var tag = Encoding.Default.GetString(block.Take(4).ToArray());

                // treat exceptions where we hash differently than usual
                if (tag == "FONT") {

                    // Not hashed, but need to find out how many bytes to skip. Best guess: tag
                    // is followed by 8 bytes of whatever, then 2 bytes size BE, followed by
                    // data.
                    blockSize = BitConverter.ToInt16(buf
                        .Skip(i + 17)
                        .Take(2)
                        .Reverse() // convert to big endian
                        .ToArray(), 0
                        );
                    // fonts are ignored, so just update the pointer and continue
                    i += 15;

                } else if (tag == "CODE") {

                    // In here, the data starts with 4 size bytes again. This is a special case,
                    // what's hashed now is only the tag and the data *after* the 4 size bytes.
                    // concretely, we have:
                    //
                    //   [4 bytes] size of block | `blockSize` above
                    //   [4 bytes] tag name      | `tag`
                    //   [4 bytes] size of code  | `blockSize` below
                    //   [n bytes] code          | `block` below
                    //
                    i += 8;
                    blockSize = BitConverter.ToInt32(buf, i);
                    _logger.Info("Code is {0} bytes long.", blockSize);

                    block = buf.Skip(i + 4).Take(blockSize).ToArray();
                    block = Encoding.Default.GetBytes(tag).Concat(block).ToArray();
                }

                // parse data block
                if (blockSize > 4) {
                    var data = block.Skip(4).ToArray();
                    blocks.Add(new BiffBlock(tag, data));
                    CollectStats(tag, data, stats);
                }
                i += blockSize + 4;

                // finally, add block to hash data
                hashBuf.Add(block);

            } while (i < buf.Length - 4);

            return blocks;
        }
        private CFStream GetStream(CFStorage cfstorage, string streamname)
        {
            CFStream stream = null;

            try
            {
                stream = cfstorage.GetStream(streamname);
            }
            catch (Exception)
            {
            }

            return stream;
        }