Пример #1
0
        private void FixCALs(CaesarContainer container)
        {
            int newLevel = 1;

            byte[] newFile = new byte[container.FileBytes.Length];
            Buffer.BlockCopy(container.FileBytes, 0, newFile, 0, container.FileBytes.Length);

            Console.WriteLine($"Creating a new CBF with access level requirements set at {newLevel}");
            List <DiagService> dsPendingFix = new List <DiagService>();

            using (BinaryReader reader = new BinaryReader(new MemoryStream(container.FileBytes)))
            {
                foreach (ECU ecu in container.CaesarECUs)
                {
                    foreach (DiagService ds in ecu.GlobalDiagServices)
                    {
                        if (ds.ClientAccessLevel > newLevel)
                        {
                            dsPendingFix.Add(ds);
                            Console.WriteLine($"-> {ds.Qualifier} (Level {ds.ClientAccessLevel})");
                            long fileOffset = ds.GetCALInt16Offset(reader);
                            if (fileOffset != -1)
                            {
                                newFile[fileOffset]     = (byte)newLevel;
                                newFile[fileOffset + 1] = (byte)(newLevel >> 8);
                            }
                        }
                    }
                }
                uint   checksum      = CaesarReader.ComputeFileChecksum(newFile);
                byte[] checksumBytes = BitConverter.GetBytes(checksum);
                Array.ConstrainedCopy(checksumBytes, 0, newFile, newFile.Length - 4, checksumBytes.Length);
            }

            SaveFileDialog sfd = new SaveFileDialog();

            sfd.Title  = "Specify a location to save your new CBF file";
            sfd.Filter = "CBF files (*.cbf)|*.cbf|All files (*.*)|*.*";
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                File.WriteAllBytes(sfd.FileName, newFile);
            }
        }
Пример #2
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);
                        }
                    }
        }