Skip to content

Instantly share code, notes, and snippets.

@0xced
Created October 16, 2020 19:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 0xced/0fdca517736d9979d5caecb4bc19516d to your computer and use it in GitHub Desktop.
Save 0xced/0fdca517736d9979d5caecb4bc19516d to your computer and use it in GitHub Desktop.
dnlib experiment
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<Nullable>enable</Nullable>
<InternalsAssemblyNames>none</InternalsAssemblyNames>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="dnlib" Version="3.3.2" />
<PackageReference Include="IgnoresAccessChecksToGenerator" Version="0.4.0" />
</ItemGroup>
</Project>
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using dnlib.DotNet;
namespace assemblyref
{
class Program
{
static int Main(string[] args)
{
try
{
var directory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".nuget", "packages", "ignoresaccesscheckstogenerator", "0.4.0", "tools", "net46");
var file = new FileInfo(Path.Combine(directory, "IgnoresAccessChecksToGenerator.Tasks.dll"));
var backup = new FileInfo(Path.Combine(directory, "IgnoresAccessChecksToGenerator.Tasks.backup.dll"));
var assemblyReferenceName = "Mono.Cecil";
var version = new Version(0, 11, 3, 0);
var isPatched = SetAssemblyReferenceVersion(file, assemblyReferenceName, version, backup);
var message = isPatched ? $"Patched {assemblyReferenceName} to version {version} in {file.FullName}" : $"Assembly reference {assemblyReferenceName} was already version {version} in {file.FullName}";
Console.WriteLine(message);
return 0;
}
catch (Exception exception)
{
Console.Error.WriteLine(exception);
return 1;
}
}
static bool SetAssemblyReferenceVersion(FileInfo targetFile, string assemblyReferenceName, Version assemblyReferenceVersion, FileInfo? backupFile = null)
{
var module = LoadModule(targetFile);
var assemblyReference = module.GetAssemblyRefs().FirstOrDefault(e => e.Name == assemblyReferenceName);
if (assemblyReference == null)
{
throw new AssemblyReferenceNotFoundException(module, assemblyReferenceName, module.GetAssemblyRefs().Select(e => e.Name.String).ToList());
}
if (assemblyReference.Version != assemblyReferenceVersion)
{
assemblyReference.Version = assemblyReferenceVersion;
if (backupFile != null)
{
targetFile.CopyTo(backupFile.FullName);
}
module.Write(targetFile.FullName);
return true;
}
return false;
}
private static ModuleDefMD LoadModule(FileInfo file)
{
#if true
using var stream = file.OpenRead();
return ModuleDefMD.Load(stream);
#else
using var image = new dnlib.PE.PEImage(file.FullName);
return ModuleDefMD.Load(image);
#endif
}
}
public class AssemblyReferenceNotFoundException : Exception
{
public ModuleDefMD Module { get; }
public string AssemblyReferenceName { get; }
public IReadOnlyCollection<string> AssemblyReferenceNames { get; }
public AssemblyReferenceNotFoundException(ModuleDefMD module, string assemblyReferenceName, IReadOnlyCollection<string> assemblyReferenceNames)
: base($"The module '{module}' does not contain an assembly reference to '{assemblyReferenceName}'. List of assembly references: {string.Join(", ", assemblyReferenceNames)}")
{
Module = module;
AssemblyReferenceName = assemblyReferenceName;
AssemblyReferenceNames = assemblyReferenceNames;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment