Skip to content

Commit

Permalink
Merge pull request #94 from ZehMatt/fix-93
Browse files Browse the repository at this point in the history
Fix #93: Invalidate the plugin cache if the version hash mismatches
  • Loading branch information
ZehMatt authored Dec 28, 2023
2 parents ab80ff5 + 011544a commit 62ae879
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 6 deletions.
46 changes: 40 additions & 6 deletions src/Dotx64Managed/Plugins.Builder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ internal partial class Plugins
System.Threading.AutoResetEvent WorkerWakeup = new(false);
System.Threading.CancellationTokenSource BuildCancellation = new();

const UInt32 PluginCacheMagic = 0x58746F44; // DotX.
const UInt32 PluginCacheVersion = 0x00000002;

bool RebuildInProgress = false;
bool SkipRebuilding = false;

Expand Down Expand Up @@ -204,11 +207,13 @@ void CachePluginBuild(Plugin plugin, string cacheFilePath)
using System.IO.Compression.ZipArchive zipArchive = new(fs, System.IO.Compression.ZipArchiveMode.Create);
var entry = zipArchive.CreateEntry(nameof(Plugin));
using BinaryWriter bw = new(entry.Open());
bw.Write((uint)0x4D5A); // ZM magic number ;)
bw.Write(PluginCacheMagic);
bw.Write(PluginCacheVersion);
bw.Write(Utils.GetVersionHash());
bw.Write(ComputePluginSourcesHash(plugin)); // uint32 hash
bw.Write(plugin.AssemblyPath);
bw.Write(plugin.BuildOutputPath);
bw.Write((uint)0x4D5A);
bw.Write(PluginCacheMagic);
}

bool InitializePluginFromCache(Plugin plugin, string cacheFilePath)
Expand All @@ -222,20 +227,46 @@ bool InitializePluginFromCache(Plugin plugin, string cacheFilePath)

using BinaryReader br = new(entry.Open());

if (br.ReadUInt32() != 0x4D5A) // Check magic
if (br.ReadUInt32() != PluginCacheMagic)
{
Utils.DebugPrintLine($"Invalid cache for plugin '{plugin.Path}'");
return false;
}

var cacheVersion = br.ReadUInt32();
if (cacheVersion < PluginCacheVersion)
{
Utils.DebugPrintLine($"Cache version mismatch for plugin '{plugin.Path}': {cacheVersion} < {PluginCacheVersion}");
return false;
}

var versionHash = br.ReadUInt32();
if (versionHash != Utils.GetVersionHash())
{
Utils.DebugPrintLine($"Version hash mismatch for plugin '{plugin.Path}': {versionHash} != {Utils.GetVersionHash()}");
return false;
}

uint hash = br.ReadUInt32();
if (hash != ComputePluginSourcesHash(plugin)) // Modified source files
if (hash != ComputePluginSourcesHash(plugin))
{
Utils.DebugPrintLine($"Source hash mismatch for plugin '{plugin.Path}': {hash} != {ComputePluginSourcesHash(plugin)}");
return false;
}

string assemblyPath = br.ReadString();
if (!File.Exists(assemblyPath)) // Invalid cache
if (!File.Exists(assemblyPath))
{
Utils.DebugPrintLine($"Assembly '{assemblyPath}' does not exist for plugin '{plugin.Path}'");
return false;
}
string buildOutputPath = br.ReadString();

if (br.ReadUInt32() != 0x4D5A) // Check magic
if (br.ReadUInt32() != PluginCacheMagic)
{
Utils.DebugPrintLine($"Invalid cache for plugin '{plugin.Path}'");
return false;
}

plugin.AssemblyPath = assemblyPath;
plugin.BuildOutputPath = buildOutputPath;
Expand All @@ -245,7 +276,10 @@ bool InitializePluginFromCache(Plugin plugin, string cacheFilePath)
catch (Exception ex)
{
if (ex is FormatException || ex is EndOfStreamException || ex is InvalidDataException)
{
Utils.DebugPrintLine($"Failed to read cache for plugin '{plugin.Path}': {ex.Message}");
return false;
}
throw;
}
}
Expand Down
25 changes: 25 additions & 0 deletions src/Dotx64Managed/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,31 @@ namespace Dotx64Dbg
{
public static class Utils
{
public static UInt32 VersionHash = 0x00000000;

public static UInt32 GetVersionHash()
{
if (VersionHash != 0)
return VersionHash;

// Get the hash of the executing assembly
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
var assemblyPath = assembly.Location;
var fileData = File.ReadAllBytes(assemblyPath);

// Create a simple hash of all the bytes in the assembly.
UInt32 hash = UInt32.MaxValue;
foreach (var b in fileData)
{
// Rotate and xor.
hash = (hash << 1) | (hash >> 31);
hash ^= b;
}

VersionHash = hash;
return VersionHash;
}

public static string GetRootPath()
{
var process = System.Diagnostics.Process.GetCurrentProcess();
Expand Down

0 comments on commit 62ae879

Please sign in to comment.