Example #1
0
        public static void AnalyzeChunkSubBuffer(int currentBlock, int startPos, byte[] data, ChunkAnalysisResult chunkAnalysisResult)
        {
            var intBuffer = new byte[4];
            var allHigh   = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF };

            using (var ms2 = new MemoryStream(data))
            {
                Console.WriteLine();
                Console.WriteLine($"Info for block #{currentBlock} starting at {startPos} length {data.Length} end {startPos+data.Length}");
                Console.WriteLine($"-------------------------------");
                var blockMagic = new byte[4];
                ms2.Read(blockMagic, 0, 4);

                chunkAnalysisResult.BlockMagic = blockMagic;
                Console.WriteLine($"Guessed block magic: {StringUtils.ByteArrayToHexString(blockMagic)}");
                ms2.Read(intBuffer, 0, 4);
                var pluginNameLength = BigEndian.ToInt32(intBuffer, 0);

                if (pluginNameLength < ms2.Length - ms2.Position)
                {
                    var pluginNameBuf = new byte[pluginNameLength];
                    ms2.Read(pluginNameBuf, 0, pluginNameLength);

                    if (chunkAnalysisResult.PluginName == "")
                    {
                        chunkAnalysisResult.PluginName = Encoding.BigEndianUnicode.GetString(pluginNameBuf);
                    }
                    Console.WriteLine($"Guessed plugin name: {Encoding.BigEndianUnicode.GetString(pluginNameBuf)}");
                }
                else
                {
                    ms2.Seek(-4, SeekOrigin.End);
                    var buf3 = new byte[4];
                    ms2.Read(buf3, 0, 4);

                    if (buf3.SequenceEqual(allHigh))
                    {
                        chunkAnalysisResult.EndChunk = ms2.ToByteArray();
                        Console.WriteLine("Probably the page stuff (end chunk?)");
                    }
                    else
                    {
                        ms2.Seek(0, SeekOrigin.Begin);

                        var presetBuf = new byte[data.Length];
                        ms2.Read(presetBuf, 0, data.Length);
                        chunkAnalysisResult.HasPresetNameAtEnd = true;
                        Console.WriteLine($"Probably the current preset name? Decoded: {Encoding.ASCII.GetString(presetBuf)}");
                    }
                    return;
                }

                var buf2 = new byte[4];
                ms2.Read(buf2, 0, 4);
                var empty = new byte[] { 0x00, 0x00, 0x00, 0x00 };

                if (buf2.SequenceEqual(empty))
                {
                    Console.WriteLine("Got 4x 0x00 after the plugin name");
                }
                else
                {
                    Console.WriteLine("Did NOT get 4x 0x00 after the plugin name");
                }

                ms2.Read(intBuffer, 0, 4);

                if (intBuffer.SequenceEqual(allHigh))
                {
                    ms2.Read(intBuffer, 0, 4);

                    if (intBuffer.SequenceEqual(Tfx.DEADBEEF))
                    {
                        Console.WriteLine("Empty block without data");
                    }
                    else
                    {
                        var midiBlockLength = BigEndian.ToInt32(intBuffer, 0);
                        if (ms2.Position + midiBlockLength + 4 == ms2.Length)
                        {
                            chunkAnalysisResult.HasMidi = true;

                            if (midiBlockLength == 4)
                            {
                                chunkAnalysisResult.HasEmptyMidi = true;
                            }
                            Console.WriteLine("Is probably a midi buffer");
                        }
                        else
                        {
                            Console.WriteLine("Unknown block?");
                        }
                    }
                }
                else
                {
                    var subBlockLength = BigEndian.ToInt32(intBuffer, 0);

                    if (ms2.Length - ms2.Position - 4 == subBlockLength)
                    {
                        Console.WriteLine($"Sub block length matches length {subBlockLength}");
                    }
                    else
                    {
                        Console.WriteLine("Sub block length does NOT match length");
                    }
                }


                var buf = new byte[4];
                ms2.Seek(-4, SeekOrigin.End);
                ms2.Read(buf, 0, 4);

                if (buf.SequenceEqual(Tfx.DEADBEEF))
                {
                    Console.WriteLine("Ends with DEADBEEF");
                }
                else
                {
                    Console.WriteLine("Does not end with DEADBEEF");
                }
            }
        }
Example #2
0
        public static ChunkAnalysisResult AnalyzeChunk(byte[] data, string file)
        {
            var chunkAnalysisResult = new ChunkAnalysisResult();
            var intBuffer           = new byte[4];

            Console.WriteLine($"Chunk Info for {file}");
            Console.WriteLine(
                "=======================================================================================================");
            Console.WriteLine("");


            using (var ms = new MemoryStream(data))
            {
                ms.Read(intBuffer, 0, 4);

                var totalLength      = LittleEndian.ToInt32(intBuffer, 0);
                var lengthDifference = ms.Length - totalLength - 16;
                Console.WriteLine(
                    $"Content total length: {totalLength} (length difference: {lengthDifference}, should be 0)");

                ms.Seek(12, SeekOrigin.Current);

                ms.Read(intBuffer, 0, 4);
                var numParameters = LittleEndian.ToInt32(intBuffer, 0);
                Console.WriteLine($"Num parameters: {numParameters}");

                chunkAnalysisResult.NumParameters = numParameters;
                ms.Seek(numParameters * 4, SeekOrigin.Current);

                var currentBlock = 0;
                while (true)
                {
                    currentBlock++;
                    if (ms.Position == ms.Length)
                    {
                        break;
                    }

                    ms.Read(intBuffer, 0, 4);
                    var blockLength = LittleEndian.ToInt32(intBuffer, 0);
                    var startPos    = ms.Position;
                    if (ms.Position + blockLength > ms.Length)
                    {
                        Console.WriteLine(
                            $"Error reading block starting at {ms.Position - 4}: Block length exceeds file size");
                        break;
                    }

                    if (blockLength == 0)
                    {
                        var unknownBlockStart = ms.Position;
                        ms.Read(intBuffer, 0, 4);



                        var subBlockLength = LittleEndian.ToInt32(intBuffer, 0);
                        var blockBuffer    = new byte[subBlockLength];

                        if (subBlockLength == 0)
                        {
                            Console.WriteLine();
                            Console.WriteLine($"Info for block #{currentBlock} starting at {unknownBlockStart} length {subBlockLength} end {unknownBlockStart+subBlockLength}");
                            Console.WriteLine($"-------------------------------");
                            Console.WriteLine("Empty unknown data block");
                            continue;
                        }
                        ms.Seek(-4, SeekOrigin.Current);
                        ms.Read(blockBuffer, 0, subBlockLength);

                        Console.WriteLine();
                        Console.WriteLine($"Info for block #{currentBlock} starting at {unknownBlockStart} length {subBlockLength} end {unknownBlockStart+subBlockLength}");
                        Console.WriteLine($"-------------------------------");
                        Console.WriteLine("Unknown data block");
                    }
                    else
                    {
                        var blockBuffer = new byte[blockLength];


                        ms.Read(blockBuffer, 0, blockLength);


                        AnalyzeChunkSubBuffer(currentBlock, (int)startPos, blockBuffer, chunkAnalysisResult);
                    }
                }
            }

            return(chunkAnalysisResult);
        }