Skip to content

Commit

Permalink
Automatic definition detection.
Browse files Browse the repository at this point in the history
  • Loading branch information
TBXin committed Mar 8, 2016
1 parent 211f601 commit 84eacf0
Show file tree
Hide file tree
Showing 9 changed files with 403 additions and 210 deletions.
7 changes: 6 additions & 1 deletion src/NFirmware/Firmware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,22 @@ public class Firmware
private readonly FirmwareImageBlocks m_imageBlocks;
private readonly FirmwareStringBlocks m_stringBlocks;

internal Firmware([NotNull] byte[] body, [NotNull] FirmwareImageBlocks imageBlocks, [NotNull] FirmwareStringBlocks stringBlocks)
internal Firmware([NotNull] byte[] body, [NotNull] FirmwareImageBlocks imageBlocks, [NotNull] FirmwareStringBlocks stringBlocks, [NotNull] FirmwareDefinition definition)
{
if (body == null) throw new ArgumentNullException("body");
if (imageBlocks == null) throw new ArgumentNullException("imageBlocks");
if (stringBlocks == null) throw new ArgumentNullException("stringBlocks");
if (definition == null) throw new ArgumentNullException("definition");

Body = body;
Definition = definition;
m_imageBlocks = imageBlocks;
m_stringBlocks = stringBlocks;
}

[NotNull]
public FirmwareDefinition Definition { get; private set; }

[NotNull]
internal byte[] Body { get; set; }

Expand Down
36 changes: 29 additions & 7 deletions src/NFirmware/FirmwareDefinition.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System.Globalization;
using System.Xml.Serialization;
using System.Xml.Serialization;
using JetBrains.Annotations;

namespace NFirmware
{
Expand All @@ -8,12 +8,19 @@ public class FirmwareDefinition
[XmlAttribute]
public string Name { get; set; }

[CanBeNull]
public FirmwareMarkerDefinition Marker { get; set; }

[CanBeNull]
public ImageTableDefinition ImageTable1 { get; set; }

[CanBeNull]
public ImageTableDefinition ImageTable2 { get; set; }

[CanBeNull]
public StringTableDefinition StringTable1 { get; set; }

[CanBeNull]
public StringTableDefinition StringTable2 { get; set; }

public override string ToString()
Expand Down Expand Up @@ -41,19 +48,34 @@ public abstract class FirmwareTableDefinition
[XmlIgnore]
public long OffsetFrom
{
get { return HexStringToLong(OffsetFromString); }
get { return OffsetFromString.HexStringToLong(); }
}

[XmlIgnore]
public long OffsetTo
{
get { return HexStringToLong(OffsetToString); }
get { return OffsetToString.HexStringToLong(); }
}
}

public class FirmwareMarkerDefinition
{
[XmlAttribute("Offset")]
public string OffsetFromString { get; set; }

[XmlAttribute("Bytes")]
public string MarkerBytesString { get; set; }

private static long HexStringToLong(string hexNumber)
[XmlIgnore]
public long Offset
{
get { return OffsetFromString.HexStringToLong(); }
}

[XmlIgnore]
public byte[] Marker
{
if (hexNumber.StartsWith("0x")) hexNumber = hexNumber.Substring(2);
return long.Parse(hexNumber, NumberStyles.AllowHexSpecifier);
get { return MarkerBytesString.HexStringToByteArray(); }
}
}
}
80 changes: 66 additions & 14 deletions src/NFirmware/FirmwareLoader.cs
Original file line number Diff line number Diff line change
@@ -1,40 +1,60 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using JetBrains.Annotations;

namespace NFirmware
{
public class FirmwareLoader
{
private readonly FirmwareEncoder m_encoder;

public FirmwareLoader(FirmwareEncoder encoder)
public FirmwareLoader([NotNull] FirmwareEncoder encoder)
{
if (encoder == null) throw new ArgumentNullException("encoder");
m_encoder = encoder;
}

public Firmware LoadEncrypted(string filePath, FirmwareDefinition definition)
[CanBeNull]
public Firmware TryLoadEncrypted([NotNull] string filePath, [NotNull, ItemNotNull] IEnumerable<FirmwareDefinition> definitions)
{
var bytes = LoadFile(filePath, true);
var definition = DetermineDefinition(bytes, definitions);
return definition != null ? Load(bytes, definition) : null;
}

[CanBeNull]
public Firmware TryLoadDecrypted([NotNull] string filePath, [NotNull, ItemNotNull] IEnumerable<FirmwareDefinition> definitions)
{
var bytes = LoadFile(filePath, false);
var definition = DetermineDefinition(bytes, definitions);
return definition != null ? Load(bytes, definition) : null;
}

[NotNull]
public Firmware LoadEncrypted([NotNull] string filePath, [NotNull] FirmwareDefinition definition)
{
return Load(filePath, definition, true);
}

public Firmware LoadDecrypted(string filePath, FirmwareDefinition definition)
[NotNull]
public Firmware LoadDecrypted([NotNull] string filePath, [NotNull] FirmwareDefinition definition)
{
return Load(filePath, definition, false);
}

public void SaveEncrypted(string filePath, Firmware firmware)
public void SaveEncrypted([NotNull] string filePath, [NotNull] Firmware firmware)
{
Save(filePath, firmware, true);
}

public void SaveDecrypted(string filePath, Firmware firmware)
public void SaveDecrypted([NotNull] string filePath, [NotNull] Firmware firmware)
{
Save(filePath, firmware, false);
}

private void Save(string filePath, Firmware firmware, bool encode)
private void Save([NotNull] string filePath, Firmware firmware, bool encode)
{
if (firmware == null) throw new ArgumentNullException("firmware");
if (string.IsNullOrEmpty(filePath)) throw new ArgumentNullException("filePath");
Expand All @@ -43,20 +63,34 @@ private void Save(string filePath, Firmware firmware, bool encode)
File.WriteAllBytes(filePath, data);
}

private Firmware Load(string filePath, FirmwareDefinition definition, bool decode)
private byte[] LoadFile([NotNull] string filePath, bool decode)
{
if (definition == null) throw new ArgumentNullException("definition");
if (string.IsNullOrEmpty(filePath)) throw new ArgumentNullException("filePath");

var data = File.ReadAllBytes(filePath);
data = decode ? m_encoder.Decode(data) : data;
return decode ? m_encoder.Decode(data) : data;
}

private Firmware Load([NotNull] string filePath, [NotNull] FirmwareDefinition definition, bool decode)
{
if (definition == null) throw new ArgumentNullException("definition");
if (string.IsNullOrEmpty(filePath)) throw new ArgumentNullException("filePath");

var data = LoadFile(filePath, decode);
return Load(data, definition);
}

private Firmware Load([NotNull] byte[] data, [NotNull] FirmwareDefinition definition)
{
if (data == null) throw new ArgumentNullException("data");
if (definition == null) throw new ArgumentNullException("definition");

var imageBlocks = LoadImageBlocks(data, definition);
var stringBlocks = LoadStringBlocks(data, definition);
return new Firmware(data, imageBlocks, stringBlocks);
return new Firmware(data, imageBlocks, stringBlocks, definition);
}

private FirmwareImageBlocks LoadImageBlocks(byte[] firmware, FirmwareDefinition definition)
private FirmwareImageBlocks LoadImageBlocks([NotNull] byte[] firmware, [NotNull] FirmwareDefinition definition)
{
if (firmware == null) throw new ArgumentNullException("firmware");
if (definition == null) throw new ArgumentNullException("definition");
Expand All @@ -72,7 +106,25 @@ private FirmwareImageBlocks LoadImageBlocks(byte[] firmware, FirmwareDefinition
}
}

private FirmwareStringBlocks LoadStringBlocks(byte[] firmware, FirmwareDefinition definition)
[CanBeNull]
private FirmwareDefinition DetermineDefinition([NotNull] byte[] firmwareBytes, [NotNull, ItemNotNull] IEnumerable<FirmwareDefinition> definitions)
{
if (firmwareBytes == null) throw new ArgumentNullException("firmwareBytes");
if (definitions == null) throw new ArgumentNullException("definitions");

foreach (var definition in definitions)
{
if (definition.Marker == null || string.IsNullOrEmpty(definition.Marker.OffsetFromString) || string.IsNullOrEmpty(definition.Marker.MarkerBytesString)) continue;

var bytes = firmwareBytes.Skip((int)definition.Marker.Offset).Take(definition.Marker.Marker.Length).ToArray();
if (!definition.Marker.Marker.SequenceEqual(bytes)) continue;

return definition;
}
return null;
}

private FirmwareStringBlocks LoadStringBlocks([NotNull] byte[] firmware, [NotNull] FirmwareDefinition definition)
{
if (firmware == null) throw new ArgumentNullException("firmware");
if (definition == null) throw new ArgumentNullException("definition");
Expand All @@ -88,7 +140,7 @@ private FirmwareStringBlocks LoadStringBlocks(byte[] firmware, FirmwareDefinitio
}
}

private IEnumerable<FirmwareImageMetadata> ReadImageTable<T>(ImageTableDefinition imageTableDefinition, BinaryReader reader) where T : FirmwareImageMetadata, new()
private IEnumerable<FirmwareImageMetadata> ReadImageTable<T>([CanBeNull] ImageTableDefinition imageTableDefinition, [NotNull] BinaryReader reader) where T : FirmwareImageMetadata, new()
{
if (imageTableDefinition == null) return new List<FirmwareImageMetadata>();
if (reader == null) throw new ArgumentNullException("reader");
Expand All @@ -114,7 +166,7 @@ private IEnumerable<FirmwareImageMetadata> ReadImageTable<T>(ImageTableDefinitio
return result;
}

private IEnumerable<FirmwareStringMetadata> ReadStringTable(StringTableDefinition stringTableDefinition, BinaryReader reader)
private IEnumerable<FirmwareStringMetadata> ReadStringTable([CanBeNull] StringTableDefinition stringTableDefinition, [NotNull] BinaryReader reader)
{
if (stringTableDefinition == null) return new List<FirmwareStringMetadata>();
if (reader == null) throw new ArgumentNullException("reader");
Expand Down
1 change: 1 addition & 0 deletions src/NFirmware/NFirmware.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
<Compile Include="FirmwareStringMetadata.cs" />
<Compile Include="FirmwareStringBlocks.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="StringExtensions.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
Expand Down
35 changes: 35 additions & 0 deletions src/NFirmware/StringExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using System.Globalization;
using System.Linq;
using JetBrains.Annotations;

namespace NFirmware
{
internal static class StringExtensions
{
internal static long HexStringToLong([NotNull] this string hexNumber)
{
if (string.IsNullOrEmpty(hexNumber)) throw new ArgumentNullException("hexNumber");
return long.Parse(PrepairHexString(hexNumber), NumberStyles.AllowHexSpecifier);
}

internal static byte HexStringToByte([NotNull] this string hexNumber)
{
if (string.IsNullOrEmpty(hexNumber)) throw new ArgumentNullException("hexNumber");
return byte.Parse(PrepairHexString(hexNumber), NumberStyles.AllowHexSpecifier);
}

internal static byte[] HexStringToByteArray([NotNull] this string hexNumbers)
{
if (hexNumbers == null) throw new ArgumentNullException("hexNumbers");

var numbers = hexNumbers.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
return numbers.Select(x => x.HexStringToByte()).ToArray();
}

private static string PrepairHexString(string hexNumber)
{
return hexNumber.StartsWith("0x") ? hexNumber.Substring(2) : hexNumber;
}
}
}
9 changes: 8 additions & 1 deletion src/NFirmwareEditor/Definitions.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<?xml version="1.0"?>
<ArrayOfFirmwareDefinition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<FirmwareDefinition Name="RX200 3.00">
<Marker Offset="0x90" Bytes="0xB5 0x20" />
<ImageTable1>
<OffsetFrom>0x8808</OffsetFrom>
<OffsetTo>0x8A84</OffsetTo>
Expand All @@ -13,6 +14,7 @@
</FirmwareDefinition>

<FirmwareDefinition Name="Cuboid 3.11">
<Marker Offset="0x90" Bytes="0x79 0x21" />
<ImageTable1>
<OffsetFrom>0xC65C</OffsetFrom>
<OffsetTo>0xC9E4</OffsetTo>
Expand All @@ -32,6 +34,7 @@
</FirmwareDefinition>

<FirmwareDefinition Name="Cuboid 3.10">
<Marker Offset="0x90" Bytes="0x05 0x21" />
<ImageTable1>
<OffsetFrom>0xC18C</OffsetFrom>
<OffsetTo>0xC50C</OffsetTo>
Expand All @@ -51,6 +54,7 @@
</FirmwareDefinition>

<FirmwareDefinition Name="Evic VTC Mini 3.01">
<Marker Offset="0x90" Bytes="0x99 0x1D" />
<ImageTable1>
<OffsetFrom>0xC1D4</OffsetFrom>
<OffsetTo>0xC55C</OffsetTo>
Expand All @@ -70,6 +74,7 @@
</FirmwareDefinition>

<FirmwareDefinition Name="Evic VTC Mini 3.00">
<Marker Offset="0x90" Bytes="0x0D 0x1D" />
<ImageTable1>
<OffsetFrom>0xBBBC</OffsetFrom>
<OffsetTo>0xBF3C</OffsetTo>
Expand All @@ -89,6 +94,7 @@
</FirmwareDefinition>

<FirmwareDefinition Name="Evic VTC Mini 2.00">
<Marker Offset="0x90" Bytes="0x99 0x1C" />
<ImageTable1>
<OffsetFrom>0xA914</OffsetFrom>
<OffsetTo>0xAC5C</OffsetTo>
Expand All @@ -108,6 +114,7 @@
</FirmwareDefinition>

<FirmwareDefinition Name="iStick TC100W 1.10">
<Marker Offset="0x90" Bytes="0x55 0x1A" />
<ImageTable1>
<OffsetFrom>0x7EB4</OffsetFrom>
<OffsetTo>0x812C</OffsetTo>
Expand Down

0 comments on commit 84eacf0

Please sign in to comment.