private static void ClusterSeedKeyAuthenticate(IKW1281Dialog kwp1281) { // Perform Seed/Key authentication Logger.WriteLine("Sending Custom \"Seed request\" block"); var response = kwp1281.SendCustom(new List <byte> { 0x96, 0x01 }); var responseBlocks = response.Where(b => !b.IsAckNak).ToList(); if (responseBlocks.Count == 1 && responseBlocks[0] is CustomBlock customBlock) { Logger.WriteLine($"Block: {Utils.Dump(customBlock.Body)}"); var keyBytes = VdoKeyFinder.FindKey(customBlock.Body.ToArray()); Logger.WriteLine("Sending Custom \"Key response\" block"); var keyResponse = new List <byte> { 0x96, 0x02 }; keyResponse.AddRange(keyBytes); response = kwp1281.SendCustom(keyResponse); } }
private static bool ClusterRequiresSeedKey(IKW1281Dialog kwp1281) { Logger.WriteLine("Sending Custom \"Need Seed/Key?\" block"); var response = kwp1281.SendCustom(new List <byte> { 0x96, 0x04 }); var responseBlocks = response.Where(b => !b.IsAckNak).ToList(); if (responseBlocks.Count == 1 && responseBlocks[0] is CustomBlock) { // Custom 0x04 means need to do Seed/Key // Custom 0x07 means unlocked if (responseBlocks[0].Body.First() == 0x07) { return(false); } } return(true); }
public static bool UnlockCluster(IKW1281Dialog kwp1281) { var versionBlocks = kwp1281.CustomReadSoftwareVersion(); // Now we need to send an unlock code that is unique to each ROM version Logger.WriteLine("Sending Custom \"Unlock partial EEPROM read\" block"); var softwareVersion = versionBlocks[0].Body; var unlockCodes = GetClusterUnlockCodes(softwareVersion); var unlocked = false; foreach (var unlockCode in unlockCodes) { var unlockCommand = new List <byte> { 0x9D }; unlockCommand.AddRange(unlockCode); var unlockResponse = kwp1281.SendCustom(unlockCommand); if (unlockResponse.Count != 1) { throw new InvalidOperationException( $"Received multiple responses from unlock request."); } if (unlockResponse[0].IsAck) { Logger.WriteLine( $"Unlock code for software version {KW1281Dialog.DumpMixedContent(softwareVersion)} is {Utils.Dump(unlockCode)}"); if (unlockCodes.Length > 1) { Logger.WriteLine("Please report this to the program maintainer."); } unlocked = true; break; } else if (!unlockResponse[0].IsNak) { throw new InvalidOperationException( $"Received non-ACK/NAK ${unlockResponse[0].Title:X2} from unlock request."); } } return(unlocked); }
// End top-level commands private void MapClusterEeprom(IKW1281Dialog kwp1281) { // Unlock partial EEPROM read _ = kwp1281.SendCustom(new List <byte> { 0x9D, 0x39, 0x34, 0x34, 0x40 }); var bytes = new List <byte>(); const byte blockSize = 1; for (ushort addr = 0; addr < 2048; addr += blockSize) { var blockBytes = kwp1281.ReadEeprom(addr, blockSize); blockBytes = Enumerable.Repeat( blockBytes == null ? (byte)0 : (byte)0xFF, blockSize).ToList(); bytes.AddRange(blockBytes); } var dumpFileName = _filename ?? "eeprom_map.bin"; Logger.WriteLine($"Saving EEPROM map to {dumpFileName}"); File.WriteAllBytes(dumpFileName, bytes.ToArray()); }