Ejemplo n.º 1
0
        static void VWTest(List <Definition> definitions, List <SecurityProvider> providers)
        {
            SecurityProvider vwProvider = providers.Find(x => x.GetProviderName() == "VolkswagenSA2");
            Definition       vw1        = definitions.Find(x => x.EcuName == "VW_SA2_TEST1");
            Definition       vw2        = definitions.Find(x => x.EcuName == "VW_SA2_TEST2");

            byte[] vwKey = new byte[4];
            byte[] expectedOutput;

            expectedOutput = BitUtility.BytesFromHex("3C7876D8");
            vwProvider.GenerateKey(BitUtility.BytesFromHex("A04EB1ED"), vwKey, 1, vw1.Parameters); // 0x3C7876D8

            if (!vwKey.SequenceEqual(expectedOutput))
            {
                Assert.Fail();
            }

            expectedOutput = BitUtility.BytesFromHex("6A37F02E");
            vwProvider.GenerateKey(BitUtility.BytesFromHex("1A1B1C1D"), vwKey, 1, vw2.Parameters); // 0x6a37f02e

            if (!vwKey.SequenceEqual(expectedOutput))
            {
                Assert.Fail();
            }
        }
Ejemplo n.º 2
0
        public void TryGenerateKey(byte[] inByte)
        {
            if (dgvMain.SelectedRows.Count != 1)
            {
                txtKeyValue.Text = "Please select a definition first";
                return;
            }
            int        selectedIndex = int.Parse(dgvMain.SelectedRows[0].Cells[0].Value.ToString());
            Definition definition    = Definitions[selectedIndex];

            groupBox2.Text = $"Key Generation ({definition})";

            if (definition.SeedLength != inByte.Length)
            {
                txtKeyValue.Text = $"Expecting a {definition.SeedLength}-byte seed. Current length is {inByte.Length}";
                return;
            }

            SecurityProvider provider = SecurityProvider.GetSecurityProviders().Find(x => x.GetProviderName() == definition.Provider);

            if (provider is null)
            {
                txtKeyValue.Text = $"Could not load security provider for {definition.Provider}";
                return;
            }
            byte[] outKey = new byte[definition.KeyLength];

            if (provider.GenerateKey(inByte, outKey, definition.AccessLevel, definition.Parameters))
            {
                txtKeyValue.Text = BitUtility.BytesToHex(outKey, true);
            }
            else
            {
                txtKeyValue.Text = $"Key generation was unsuccessful ({definition.Provider})";
                return;
            }
        }
Ejemplo n.º 3
0
        static void QuickTest(Definition definition, List <SecurityProvider> providers)
        {
            // Build in x86 to test, else the pinvokes will fail!

            SecurityProvider provider = providers.Find(x => x.GetProviderName() == definition.Provider);

            if (provider is null)
            {
                Console.WriteLine($"Could not find a security provider for {definition.EcuName} ({definition.Provider})");
                Assert.Fail();
                return;
            }

            string dllPath = $"{GetLibraryFolder()}{definition.Provider}_L{definition.AccessLevel}.dll";

            Console.WriteLine(dllPath);
            if (!File.Exists(dllPath))
            {
                Console.WriteLine($"Could not find the target security DLL to verify with. {definition.EcuName} ({definition.Provider})");
                Assert.Fail();
                return;
            }

            Console.WriteLine($"Running QuickTest for {definition.EcuName} ({definition.Provider})");
            DllContext context = new DllContext(dllPath, false);

            Tuple <uint, int, int> match = context.AccessLevels.Find(x => x.Item1 == definition.AccessLevel);

            if (match is null)
            {
                Console.WriteLine($"DLL does not support access level {definition.AccessLevel}");
                Assert.Fail();
                return;
            }

            List <byte[]> TestInput = new List <byte[]>();

            foreach (GeneratedByteType byteType in Enum.GetValues(typeof(GeneratedByteType)))
            {
                TestInput.Add(GenerateBytes(definition.SeedLength, byteType));
            }

            bool matchesAreValid = true;

            foreach (byte[] testRow in TestInput)
            {
                byte[] outKey = new byte[definition.KeyLength];
                if (provider.GenerateKey(testRow, outKey, definition.AccessLevel, definition.Parameters))
                {
                    byte[] dllResult = context.GenerateKeyAuto((uint)definition.AccessLevel, testRow);
                    matchesAreValid &= outKey.SequenceEqual(dllResult);
                    Console.WriteLine($"In: {BitUtility.BytesToHex(testRow)} Out: {BitUtility.BytesToHex(outKey)} DLL: {BitUtility.BytesToHex(dllResult)}");
                }
            }
            string testResult = matchesAreValid ? "Passed" : "Failed";

            Console.WriteLine($"QuickTest {testResult}");
            if (!matchesAreValid)
            {
                Assert.Fail();
            }
        }
Ejemplo n.º 4
0
        static void Main(string[] args)
        {
            bool showHelp        = false;
            bool showDefinitions = false;

            int    accessLevel  = 1;
            string databasePath = "db.json";
            string seedText     = "";
            string ecuName      = "";
            string prefix       = "";

            OptionSet options = new OptionSet()
            {
                {
                    "d|database=", "Path to the JSON definition database",
                    (string v) => databasePath = v
                },
                {
                    "s|seed=", "Seed value as received from ECU",
                    (string v) => seedText = v
                },
                {
                    "n|name=", "Target ECU name",
                    (string v) => ecuName = v
                },
                {
                    "l|level=", "Access level",
                    (int v) => accessLevel = v
                },
                {
                    "h|help", "Show this message and exit",
                    v => showHelp = v != null
                },
                {
                    "e|list", "Show a list of ECU definitions, then exit",
                    v => showDefinitions = v != null
                },
                {
                    "p|prefix=", "Prefix this string on successful key generation",
                    (string v) => prefix = v
                },
            };

            List <string> extraArgs;

            try
            {
                extraArgs = options.Parse(args);
            }
            catch (OptionException ex)
            {
                Console.WriteLine($"UnlockECU exception: {ex.Message}");
                Console.WriteLine("Try `consoleunlockecu --help' for more information.");
                return;
            }

            if (showHelp)
            {
                ShowHelp(options);
                return;
            }

            // check params if they are valid first
            if (!File.Exists(databasePath))
            {
                Console.WriteLine($"Could not open definition database file. Please check if the database exists at \"{databasePath}\"");
                return;
            }

            string definitionJson = "";

            try
            {
                definitionJson = File.ReadAllText(databasePath);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"UnlockECU exception while reading database : {ex.Message}");
                return;
            }

            List <Definition> definitions = new List <Definition>();

            try
            {
                definitions = System.Text.Json.JsonSerializer.Deserialize <List <Definition> >(definitionJson);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"UnlockECU exception while parsing database : {ex.Message}. Please check if the JSON database file is valid.");
                return;
            }

            if (showDefinitions)
            {
                Console.WriteLine($"UnlockECU: {definitions.Count} definitions available in {databasePath}");
                foreach (Definition d in definitions)
                {
                    Console.Write($"{d.EcuName} ({d.Origin}): Level {d.AccessLevel}, Seed Length: {d.SeedLength}, Key Length: {d.KeyLength}, Provider: {d.Provider}\n");
                }
                return;
            }

            if (ecuName.Length == 0)
            {
                Console.WriteLine($"UnlockECU: ECU name cannot be empty.");
                ShowHelp(options);
                return;
            }

            Definition matchingDefinition = Definition.FindDefinition(definitions, ecuName, accessLevel);

            if (matchingDefinition is null)
            {
                Console.WriteLine($"UnlockECU exception: Could not find a definition that matches {ecuName} (level {accessLevel})");
                return;
            }

            // clean up user's seed input
            bool   validHex    = true;
            string cleanedText = seedText.Replace(" ", "").Replace("\r", "").Replace("\n", "").Replace("\t", "").Replace("-", "").ToUpper();

            if (cleanedText.Length % 2 != 0)
            {
                validHex = false;
            }
            if (!System.Text.RegularExpressions.Regex.IsMatch(cleanedText, @"\A\b[0-9a-fA-F]+\b\Z"))
            {
                validHex = false;
            }

            byte[] seed = new byte[] { };
            if (validHex)
            {
                seed = BitUtility.BytesFromHex(cleanedText);
            }
            else if (matchingDefinition.SeedLength == 0)
            {
                // do nothing, array is already empty
            }
            else
            {
                Console.WriteLine($"UnlockECU exception: ECU {matchingDefinition.EcuName} requires a valid {matchingDefinition.SeedLength}-byte seed");
                return;
            }


            // attempt to generate the key
            SecurityProvider provider = SecurityProvider.GetSecurityProviders().Find(x => x.GetProviderName() == matchingDefinition.Provider);

            if (provider is null)
            {
                Console.WriteLine($"UnlockECU exception: Could not load security provider for {matchingDefinition.EcuName} ({matchingDefinition.Provider})");
                return;
            }
            byte[] outKey = new byte[matchingDefinition.KeyLength];

            if (provider.GenerateKey(seed, outKey, matchingDefinition.AccessLevel, matchingDefinition.Parameters))
            {
                Console.Write($"{prefix}{BitUtility.BytesToHex(outKey)}");
                return;
            }
            else
            {
                Console.WriteLine($"UnlockECU exception: Key generation was unsuccessful for {matchingDefinition.EcuName} ({matchingDefinition.Provider})");
                return;
            }
        }