예제 #1
0
        private void exportSplicedFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (FlashContainer is null)
            {
                return;
            }
            if (!LoadMappedAddresses())
            {
                return;
            }

            /*
             * we need to..
             *  - get the fileoffsets of the segment sizes
             *  - get the fileoffsets of the segment addresses
             *  - get the fileoffset of the flash start address
             *
             *  - patch all the fileoffsets (size+address) with the new value
             */

            int flashDataFileOffset = FlashContainer.CaesarFlashHeader.CffHeaderSize + FlashContainer.CaesarFlashHeader.LanguageBlockLength + 0x414;

            byte[] nonFlashData = FlashBytes.Take(flashDataFileOffset).ToArray();

            using (BinaryReader reader = new BinaryReader(new MemoryStream(FlashBytes)))
                using (BinaryWriter nonFlashWriter = new BinaryWriter(new MemoryStream(nonFlashData)))
                    using (BinaryWriter flashPayloadWriter = new BinaryWriter(new MemoryStream()))
                    {
                        int segmentCursor = 0;

                        for (int i = 0; i < FlashContainer.CaesarFlashHeader.DataBlocks.Count; i++)
                        {
                            FlashDataBlock db = FlashContainer.CaesarFlashHeader.DataBlocks[i];
                            // read block offset fileoffset
                            long blockOffsetFileOffset = db.GetFlashDataOffset(reader);

                            // patch segment length on filebytes
                            nonFlashWriter.BaseStream.Seek(blockOffsetFileOffset, SeekOrigin.Begin);
                            nonFlashWriter.Write(segmentCursor);

                            int localBlockLength = 0;
                            for (int j = 0; j < db.FlashSegments.Count; j++)
                            {
                                FlashSegment seg = db.FlashSegments[j];
                                // check: which fields are mutable when splicing

                                long offset =
                                    db.FlashData +                                         // somewhat mutable : probably if there's more than 1 datablock, this value will be nonzero
                                    FlashContainer.CaesarFlashHeader.CffHeaderSize +       // constant
                                    FlashContainer.CaesarFlashHeader.LanguageBlockLength + // constant
                                    segmentCursor +                                        // mutable, see below
                                    0x414;                                                 // constant

                                byte[] segmentPayload = FlashData[i][j];
                                if (SplicePath[i][j].Length > 0)
                                {
                                    segmentPayload = File.ReadAllBytes(SplicePath[i][j]);
                                }

                                int segmentMappedAddress = MappedAddresses[i][j];


                                // read segment length's offset
                                long segmentLengthFileOffset = seg.GetSegmentLengthFileOffset(reader);
                                // read segment's mapped address
                                long segmentMappedAddressFileOffset = seg.GetMappedAddressFileOffset(reader);

                                // patch segment length on filebytes
                                nonFlashWriter.BaseStream.Seek(segmentLengthFileOffset, SeekOrigin.Begin);
                                nonFlashWriter.Write(segmentPayload.Length);
                                // patch segment's mapped address
                                nonFlashWriter.BaseStream.Seek(segmentMappedAddressFileOffset, SeekOrigin.Begin);
                                nonFlashWriter.Write(segmentMappedAddress);

                                // increment segment offset for db.flashdata
                                segmentCursor    += segmentPayload.Length;
                                localBlockLength += segmentPayload.Length;

                                // append flash payload to temp buffer
                                flashPayloadWriter.Write(segmentPayload);
                            }

                            // refresh the block size
                            // read block size fileoffset
                            long blockSizeFileOffset = db.GetBlockLengthOffset(reader);

                            // patch block length
                            nonFlashWriter.BaseStream.Seek(blockSizeFileOffset, SeekOrigin.Begin);
                            nonFlashWriter.Write(localBlockLength);
                        }


                        // take the non-flash part of the bytes that we patched...
                        // .. then merge it with the flash section that we rebuilt
                        byte[] flashPayload   = ((MemoryStream)flashPayloadWriter.BaseStream).ToArray();
                        byte[] nonFlashPrefix = ((MemoryStream)nonFlashWriter.BaseStream).ToArray();

                        byte[] result = new byte[flashPayload.Length + nonFlashPrefix.Length + 4];
                        Array.ConstrainedCopy(nonFlashPrefix, 0, result, 0, nonFlashPrefix.Length);
                        Array.ConstrainedCopy(flashPayload, 0, result, nonFlashPrefix.Length, flashPayload.Length);

                        // restore the checksum
                        uint checksum = CaesarReader.ComputeFileChecksumLazy(result);

                        result[result.Length - 4] = (byte)((checksum >> 0) & 0xFF);
                        result[result.Length - 3] = (byte)((checksum >> 8) & 0xFF);
                        result[result.Length - 2] = (byte)((checksum >> 16) & 0xFF);
                        result[result.Length - 1] = (byte)((checksum >> 24) & 0xFF);

                        // save the result
                        SaveFileDialog sfd = new SaveFileDialog();
                        sfd.Title  = "Specify a location to save your new CFF file";
                        sfd.Filter = "CFF files (*.cff)|*.cff|All files (*.*)|*.*";
                        if (sfd.ShowDialog() == DialogResult.OK)
                        {
                            File.WriteAllBytes(sfd.FileName, result);
                        }
                    }
        }
예제 #2
0
        private void PresentRows()
        {
            if (FlashContainer is null)
            {
                return;
            }

            DataTable dt = new DataTable();

            foreach (string header in new string[] { "Block #", "Block Name", "Block Description", "Segment #", "Segment Name", "ECU Target Address (Editable)", "Original Length", "Original Offset", "Splice Mode" })
            {
                dt.Columns.Add(header, typeof(string));
            }
            dgvMain.DataSource = dt;

            for (int i = 0; i < FlashContainer.CaesarFlashHeader.DataBlocks.Count; i++)
            {
                FlashDataBlock db         = FlashContainer.CaesarFlashHeader.DataBlocks[i];
                long           fileCursor = 0;

                for (int j = 0; j < db.FlashSegments.Count; j++)
                {
                    FlashSegment seg = db.FlashSegments[j];

                    long offset =
                        db.FlashData +
                        FlashContainer.CaesarFlashHeader.CffHeaderSize +
                        FlashContainer.CaesarFlashHeader.LanguageBlockLength +
                        fileCursor +
                        0x414;

                    fileCursor += seg.SegmentLength;

                    // Console.WriteLine($"Segment: {seg.SegmentName} mapped to 0x{seg.FromAddress:X} with size 0x{seg.SegmentLength:X}");
                    string spliceModeForRow = SplicePath[i][j].Length == 0 ? "Inherit Original" : SplicePath[i][j];

                    dt.Rows.Add(
                        i.ToString(),
                        db.Qualifier,
                        FlashContainer.CaesarCTFHeader.CtfLanguages[0].GetString(db.Description),
                        j.ToString(),
                        seg.SegmentName,
                        seg.FromAddress.ToString("X"),
                        seg.SegmentLength.ToString("X"),
                        offset.ToString("X"),
                        spliceModeForRow
                        );
                }
            }

            dgvMain.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;

            dgvMain.Columns[0].ReadOnly = true;
            dgvMain.Columns[1].ReadOnly = true;
            dgvMain.Columns[2].ReadOnly = true;
            dgvMain.Columns[3].ReadOnly = true;
            dgvMain.Columns[4].ReadOnly = true;
            dgvMain.Columns[5].ReadOnly = false;
            dgvMain.Columns[6].ReadOnly = true;
            dgvMain.Columns[7].ReadOnly = true;
            dgvMain.Columns[8].ReadOnly = false;

            dgvMain.Columns[dgvMain.Columns.Count - 1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
        }