コード例 #1
0
        // debug stub, not intended for direct execution
        private void SetSessionStub(ECUConnection Connection)
        {
            return;

            Console.WriteLine("Entering bootmode");
            Connection.SendMessage(BitUtility.BytesFromHex("1002"));

            Console.WriteLine("Requesting for seed");
            byte[] seed = Connection.SendMessage(BitUtility.BytesFromHex("2705"));
            SecurityAccess.SecurityAutoLogin.QueryUnlockEcu(seed.Skip(2).ToArray(), "X_4", 5, out byte[] key);

            Console.Write("Authenticating for bootmode.. ");
            List <byte> keyResponse = new List <byte>(new byte[] { 0x27, 0x06 });

            keyResponse.AddRange(key);
            byte[] authResponse = Connection.SendMessage(keyResponse);
            Console.WriteLine(BitUtility.BytesToHex(authResponse));

            // remind myself to write fingerprint
            Console.WriteLine($"2EF15A 00 0004 150213 00000000\r\n2EF15A 01 0004 150213 00000000\r\n3101FF00");

            /*
             * int blockId = 1; // block0: CODE,  block1: DATA
             * Console.WriteLine($"Writing fingerprint");
             * //  2e f1 5a 00 00 04 15 02 16 00 00 00 00
             * Connection.SendMessage(BitUtility.BytesFromHex($"2EF15A {blockId:X2} 0004 150213 00000000"));
             *
             * // 2EF15A 00 0004 150213 00000000
             * // 2EF15A 01 0004 150213 00000000
             *
             * Console.WriteLine($"Erasing block {blockId}");
             * Connection.SendMessage(BitUtility.BytesFromHex("3101FF00"));
             * Console.WriteLine("Ready to accept flash data");
             */
        }
コード例 #2
0
 public static bool TryReadKW2C3PEChassisNumber(ECUConnection connection, out string chassisNumber)
 {
     chassisNumber = "";
     byte[] response = connection.SendMessage(new byte[] { 0x1A, 0x90 }); // VIN current
     if (response.Length != 19)                                           // 5A 90 + 17byte vin
     {
         return(false);
     }
     if (response[0] != 0x5A)
     {
         return(false);
     }
     chassisNumber = Encoding.ASCII.GetString(response.Skip(2).ToArray());
     return(true);
 }
コード例 #3
0
 public static bool TryReadUDSChassisNumber(ECUConnection connection, out string chassisNumber)
 {
     chassisNumber = "";
     byte[] response = connection.SendMessage(new byte[] { 0x22, 0xF1, 0xA0 });
     if (response.Length != 20) // 62 F1 A0 + 17byte vin
     {
         return(false);
     }
     if (response[0] != 0x62)
     {
         return(false);
     }
     chassisNumber = Encoding.ASCII.GetString(response.Skip(3).ToArray());
     return(true);
 }
コード例 #4
0
 private void txtJ2534Input_KeyDown(object sender, KeyEventArgs e)
 {
     if (e.KeyCode == Keys.Enter)
     {
         e.Handled = true;
         string inText = txtJ2534Input.Text;
         txtJ2534Input.Text = "";
         if (BitUtility.CheckHexValid(inText))
         {
             byte[] requestData = BitUtility.BytesFromHex(inText.Replace(" ", "").ToUpper());
             byte[] response    = Connection.SendMessage(requestData);
             Console.WriteLine($"ECU:  {BitUtility.BytesToHex(response, true)}");
         }
         else
         {
             Console.WriteLine($"Could not understand provided hex input: '{inText}'");
         }
     }
 }
コード例 #5
0
        private void btnRead_Click(object sender, EventArgs e)
        {
            if (!FetchAndValidateInput(out uint sourceAddress, out uint destinationAddress, out uint bufferSize))
            {
                return;
            }

            int  strideWidth      = decimal.ToInt32(nudIOWidth.Value);
            int  addressWidth     = decimal.ToInt32(nudAddressWidth.Value);
            int  ioDigitCount     = GetMemoryDigitCount(strideWidth);
            byte readCmd          = decimal.ToByte(nudReadCmd.Value);
            byte positiveResponse = (byte)(readCmd + 0x40);

            byte alfid = GetAddressAndLengthFormatIdentifier(
                addressWidth,
                ioDigitCount
                );


            byte[] memoryBuffer = new byte[bufferSize];
            uint   readCursor   = sourceAddress;
            int    bufferCursor = 0;
            bool   hasBadReads  = false;

            while (readCursor < destinationAddress)
            {
                uint remainder = destinationAddress - readCursor;
                int  readSize  = strideWidth;
                if (readSize > remainder)
                {
                    readSize = (int)remainder;
                }
                List <byte> readCommand = CreateReadCommand(readCmd, alfid, readCursor, addressWidth, readSize);
                //byte[] response =

                //MessageBox.Show($"cmd: {BitUtility.BytesToHex(readCommand.ToArray(), true)}, width: {readSize}, remainder: {remainder}");
                byte[] response = Connection.SendMessage(readCommand);
                if (response[0] == positiveResponse)
                {
                    Array.ConstrainedCopy(response, 1, memoryBuffer, bufferCursor, readSize);
                }
                else
                {
                    hasBadReads = true;
                }

                readCursor   += (uint)readSize;
                bufferCursor += readSize;
            }

            OriginalBuffer = memoryBuffer;

            /*
             * HexboxBuffer = new byte[memoryBuffer.Length];
             * Array.ConstrainedCopy(memoryBuffer, 0, HexboxBuffer, 0, memoryBuffer.Length);
             */
            Hexbox.LineInfoOffset = sourceAddress;
            Hexbox.ByteProvider   = new DynamicByteProvider(OriginalBuffer);

            if (hasBadReads)
            {
                MessageBox.Show("One or more read requests were rejected by the ECU, and the empty blocks were substituted with zeros. \r\n\r\n" +
                                "Please check if the memory address is valid to the ECU, and if the ECU has been unlocked if required.\r\n\r\n" +
                                "If the memory region has protected bytes, consider loading a smaller, more specific range with a I/O width of 1 to skip past the protected bytes.",
                                "Warning: Invalid reads");
            }
        }
コード例 #6
0
        private void StartDownload()
        {
            int sumBytesTransferred = 0;
            int sumBytes            = 0;

            foreach (FlashBlock block in FlashBlocks)
            {
                sumBytes += block.Payload.Length;
            }

            GenericLoader loader = new GenericLoader();

            loader.Text    = "Reading from ECU";
            loader.TopMost = true;
            loader.Show();
            Application.DoEvents();

            foreach (FlashBlock block in FlashBlocks)
            {
                byte[] startDownloadCmd = CreateDownloadRequest(block.Address, (uint)block.Payload.Length);

                byte[] response = connection.SendMessage(startDownloadCmd); // comment this, uncomment below if dryrun
                //byte[] response = BitUtility.BytesFromHex("74 20 00 03");
                if (response.Length < 2)
                {
                    MessageBox.Show($"Error: ECU sent an incorrectly sized response when initiating download for block {Path.GetFileNameWithoutExtension(block.Path)}");
                    break;
                }
                if (response[0] != startDownloadCmd[0] + 0x40)
                {
                    MessageBox.Show($"Error: ECU sent a non-positive response ({BitUtility.BytesToHex(response)}) for block {Path.GetFileNameWithoutExtension(block.Path)}");
                    break;
                }
                // read alfid to know memory size description's width
                byte rxAlfid = response[1];
                // we are only expecting a size value
                if ((rxAlfid & 0xF) > 0)
                {
                    MessageBox.Show($"Error: Could not understand ECU ALFID response ({BitUtility.BytesToHex(response)}) for block {Path.GetFileNameWithoutExtension(block.Path)}");
                    break;
                }
                // find out how wide the memory size description is
                int         memSize  = rxAlfid >> 4;
                List <byte> memBytes = response.Skip(2).Take(memSize).ToList();
                if (memBytes.Count != memSize)
                {
                    MessageBox.Show($"Error: Could not understand ECU ALFID response (size mismatch) ({BitUtility.BytesToHex(response)}) for block {Path.GetFileNameWithoutExtension(block.Path)}");
                    break;
                }
                // parse the memory size desc as a BE integer
                uint messageSize = 0;
                for (int i = 0; i < memBytes.Count; i++)
                {
                    messageSize <<= 8;
                    messageSize  |= memBytes[i];
                }
                // debug: uncomment to cap msg size at 0x100, normally 0xF02, blocksize = 0xF00
                // messageSize = 0x102;
                int blockSize       = (int)messageSize - 2;
                int totalBlockCount = (int)(block.Payload.Length / blockSize);
                int remainderBytes  = block.Payload.Length % blockSize;
                if (remainderBytes != 0)
                {
                    totalBlockCount++;
                }

                // reconfigure connection for block transfer
                connection.TesterPresentTimer.Enabled = false;
                RaiseSTMin();

                byte[] dataBlock = new byte[messageSize];

                loader.SetProgressMax(totalBlockCount);

                for (int blockCounter = 0; blockCounter < totalBlockCount; blockCounter++)
                {
                    dataBlock[0] = 0x36;
                    dataBlock[1] = (byte)((blockCounter + 1) & 0xFF);

                    // if this is the last block, and there is a remainder block, write only the remainder
                    if (((blockCounter + 1) == totalBlockCount) && (remainderBytes != 0))
                    {
                        Array.ConstrainedCopy(block.Payload, blockCounter * blockSize, dataBlock, 2, remainderBytes);
                        dataBlock = dataBlock.Take(2 + remainderBytes).ToArray();
                    }
                    else
                    {
                        Array.ConstrainedCopy(block.Payload, blockCounter * blockSize, dataBlock, 2, blockSize);
                    }

                    byte[] transferResponse = connection.SendMessage(dataBlock); // comment this, uncomment below if dryrun
                    //byte[] transferResponse = new byte[] { 0x76, 0x00 };
                    if ((transferResponse.Length > 0) && (transferResponse[0] == 0x76))
                    {
                        // no need to check block index, if the ecu accepts it, continue
                    }
                    else
                    {
                        MessageBox.Show($"Error: Data transfer rejected by ECU ({BitUtility.BytesToHex(transferResponse)}) for block {Path.GetFileNameWithoutExtension(block.Path)}");
                        break;
                    }

                    // update progress
                    sumBytesTransferred += dataBlock.Length - 2;
                    // loader.Text = $"Writing to ECU : 0x{sumBytesTransferred:X8} of 0x{sumBytes:X8}";
                    loader.Text = $"Writing to ECU : block {blockCounter} of 0x{totalBlockCount}";
                    loader.SetProgressValue(blockCounter);
                    Application.DoEvents();
                    // fixme: show two progressbars, one for the block# and another for the individual block's %
                }

                byte[] exitTransferResponse = connection.SendMessage(new byte[] { 0x37 });// ------------------ patch if debugging
                if (!((exitTransferResponse.Length > 0) && (exitTransferResponse[0] == 0x77)))
                {
                    MessageBox.Show($"Error: Exit transfer rejected by ECU ({BitUtility.BytesToHex(exitTransferResponse)}) for block {Path.GetFileNameWithoutExtension(block.Path)}");
                    break;
                }
            }

            // restore prior connection status
            connection.TesterPresentTimer.Enabled = true;
            ResetSTMin();

            loader.Close();
            MessageBox.Show("Download completed");
        }
コード例 #7
0
        private void btnRead_Click(object sender, EventArgs e)
        {
            if (!FetchAndValidateInput(out uint sourceAddress, out uint destinationAddress, out uint bufferSize))
            {
                return;
            }

            int  strideWidth      = decimal.ToInt32(nudIOWidth.Value);
            int  addressWidth     = decimal.ToInt32(nudAddressWidth.Value);
            int  ioDigitCount     = GetMemoryDigitCount(strideWidth);
            byte readCmd          = decimal.ToByte(nudReadCmd.Value);
            byte positiveResponse = (byte)(readCmd + 0x40);

            byte alfid = GetAddressAndLengthFormatIdentifier(
                addressWidth,
                ioDigitCount
                );

            GenericLoader loader = new GenericLoader();

            loader.Text = "Reading from ECU";
            loader.SetProgressMax((int)(destinationAddress - sourceAddress));
            loader.SetProgressValue(0);
            loader.TopMost = true;
            loader.Show();
            Application.DoEvents();

            byte[] memoryBuffer = new byte[bufferSize];
            uint   readCursor   = sourceAddress;
            int    bufferCursor = 0;
            bool   hasBadReads  = false;

            while (readCursor < destinationAddress)
            {
                loader.Text = $"Reading from ECU : 0x{readCursor:X8}";
                loader.SetProgressValue((int)(readCursor - sourceAddress));
                Application.DoEvents();

                uint remainder = destinationAddress - readCursor;
                int  readSize  = strideWidth;
                if (readSize > remainder)
                {
                    readSize = (int)remainder;
                }
                List <byte> readCommand = CreateReadCommand(readCmd, alfid, readCursor, addressWidth, readSize);

                byte[] response = Connection.SendMessage(readCommand);
                if (response[0] == positiveResponse)
                {
                    Array.ConstrainedCopy(response, 1, memoryBuffer, bufferCursor, readSize);
                }
                else
                {
                    hasBadReads = true;
                }

                readCursor   += (uint)readSize;
                bufferCursor += readSize;
            }

            loader.Close();
            Application.DoEvents();

            OriginalBuffer = memoryBuffer;

            Hexbox.LineInfoOffset = sourceAddress;
            Hexbox.ByteProvider   = new DynamicByteProvider(OriginalBuffer);

            if (hasBadReads)
            {
                MessageBox.Show("One or more read requests were rejected by the ECU, and the empty blocks were substituted with zeros. \r\n\r\n" +
                                "Please check if the memory address is valid to the ECU, and if the ECU has been unlocked if required.\r\n\r\n" +
                                "If the memory region has protected bytes, consider loading a smaller, more specific range with a I/O width of 1 to skip past the protected bytes.",
                                "Warning: Invalid reads");
            }
        }