Add ConsoleUnlockECU, schema change to include aliases

This commit is contained in:
JinGen Lim 2021-02-14 23:25:23 +08:00
parent 2c8b4ea9cc
commit 8dffb2b0ac
11 changed files with 5170 additions and 26 deletions

View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<ApplicationIcon>unlockecu-256.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\UnlockECU\UnlockECU.csproj" />
</ItemGroup>
</Project>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,187 @@
using Mono.Options;
using System;
using System.Collections.Generic;
using System.IO;
using UnlockECU;
namespace ConsoleUnlockECU
{
class Program
{
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;
}
}
static void ShowHelp(OptionSet p)
{
Console.WriteLine("Usage: consoleunlockecu [OPTIONS]");
Console.WriteLine("Generates a key for a ECU seed-key challenge");
Console.WriteLine();
Console.WriteLine("Options:");
Console.WriteLine();
p.WriteOptionDescriptions(Console.Out);
}
}
}

View File

@ -0,0 +1,8 @@
{
"profiles": {
"ConsoleUnlockECU": {
"commandName": "Project",
"commandLineArgs": "-n CRD3NFZ -l 11 -s 11223344"
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

View File

@ -5,9 +5,11 @@ VisualStudioVersion = 16.0.30711.63
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnlockECU", "UnlockECU\UnlockECU.csproj", "{9DBD6CB7-68B3-4801-95B7-D760C49E2A83}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VisualUnlockECU", "VisualUnlockECU\VisualUnlockECU.csproj", "{FA2EF721-9B46-4EB9-8444-0ABAF6F5185A}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VisualUnlockECU", "VisualUnlockECU\VisualUnlockECU.csproj", "{FA2EF721-9B46-4EB9-8444-0ABAF6F5185A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnlockECUTests", "UnlockECUTests\UnlockECUTests.csproj", "{6252DB08-EFD2-4889-B97F-090726D9DC9C}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnlockECUTests", "UnlockECUTests\UnlockECUTests.csproj", "{6252DB08-EFD2-4889-B97F-090726D9DC9C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleUnlockECU", "ConsoleUnlockECU\ConsoleUnlockECU.csproj", "{37C58044-BEC1-41B0-8021-3417C3E4B9E3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -27,6 +29,10 @@ Global
{6252DB08-EFD2-4889-B97F-090726D9DC9C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6252DB08-EFD2-4889-B97F-090726D9DC9C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6252DB08-EFD2-4889-B97F-090726D9DC9C}.Release|Any CPU.Build.0 = Release|Any CPU
{37C58044-BEC1-41B0-8021-3417C3E4B9E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{37C58044-BEC1-41B0-8021-3417C3E4B9E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{37C58044-BEC1-41B0-8021-3417C3E4B9E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{37C58044-BEC1-41B0-8021-3417C3E4B9E3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -9,6 +9,7 @@ namespace UnlockECU
public class Definition
{
public string EcuName { get; set; }
public List<string> Aliases { get; set; }
public int AccessLevel { get; set; }
public int SeedLength { get; set; }
public int KeyLength { get; set; }
@ -33,6 +34,24 @@ namespace UnlockECU
return sb.ToString();
*/
}
public static Definition FindDefinition(List<Definition> definitions, string ecuName, int accessLevel)
{
foreach (Definition d in definitions)
{
if (accessLevel != d.AccessLevel)
{
continue;
}
if (ecuName != d.EcuName.ToUpper())
{
if (!d.Aliases.Contains(ecuName))
{
continue;
}
}
return d;
}
return null;
}
}
}

View File

@ -18,8 +18,17 @@ namespace VisualUnlockECU
List<Definition> Definitions;
public MainForm()
{
string definitionJson = File.ReadAllText("db.json");
Definitions = System.Text.Json.JsonSerializer.Deserialize<List<Definition>>(definitionJson);
string dbFile = "db.json";
if (File.Exists(dbFile))
{
string definitionJson = File.ReadAllText(dbFile);
Definitions = System.Text.Json.JsonSerializer.Deserialize<List<Definition>>(definitionJson);
}
else
{
Definitions = new List<Definition>();
MessageBox.Show("No definitions loaded. Check if the file 'db.json' is accessible in the same folder as VisualUnlockECU.");
}
InitializeComponent();
}

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
<OutputType>Exe</OutputType>
<TargetFramework>net5.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<ApplicationIcon>key.ico</ApplicationIcon>
<ApplicationIcon>unlockecu-256.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB