Last active
March 9, 2018 05:49
-
-
Save sailro/be4d1a3f3333b728f94a170af9c89f8a to your computer and use it in GitHub Desktop.
Check Authenticode, StrongName and assembly references
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Text; | |
using Mono.Cecil; | |
using System.Security.Cryptography.X509Certificates; | |
namespace CheckFiles | |
{ | |
[Flags] | |
enum CheckTypes | |
{ | |
Nothing = 0, | |
Authenticode = 1, | |
StrongName = 2, | |
References = 4, | |
All = Authenticode + StrongName + References | |
} | |
class Program | |
{ | |
public const string VSPublicKeyToken = "b03f5f7f11d50a3a"; | |
public const string VSTUPublicKeyToken = "31bf3856ad364e35"; | |
static int Main(string[] args) | |
{ | |
if (args.Length < 2) | |
{ | |
Console.WriteLine("Usage: <assembly> <Authenticode|StrongName|References|All> <version for reference check>"); | |
return 1; | |
} | |
try | |
{ | |
var filename = args[0]; | |
var checks = (CheckTypes) Enum.Parse(typeof(CheckTypes), args[1]); | |
Version version; | |
if (args.Length == 2 && checks.HasFlag(CheckTypes.References)) | |
throw new Exception("Version is missing"); | |
else | |
version = Version.Parse(args[2]); | |
var mdef = ModuleDefinition.ReadModule(filename); | |
if (checks.HasFlag(CheckTypes.Authenticode)) | |
CheckAuthenticode(filename); | |
if (checks.HasFlag(CheckTypes.StrongName)) | |
CheckStrongName(mdef); | |
if (checks.HasFlag(CheckTypes.References)) | |
CheckReferences(mdef, version); | |
} | |
catch (Exception e) | |
{ | |
Console.WriteLine(e.Message); | |
return 2; | |
} | |
return 0; | |
} | |
public static string ByteToString(byte[] input) | |
{ | |
if (input != null) | |
{ | |
var sb = new StringBuilder(); | |
foreach (var b in input) | |
sb.Append(b.ToString("x2")); | |
return sb.ToString(); | |
} | |
return string.Empty; | |
} | |
private static void CheckAuthenticode(string filename) | |
{ | |
X509Certificate cert = null; | |
try | |
{ | |
cert = X509Certificate.CreateFromSignedFile(filename); | |
} | |
catch (Exception) | |
{ | |
throw new Exception($"Unable to get certificate from {filename}"); | |
} | |
if (cert == null || !cert.Issuer.Contains("Microsoft")) | |
throw new Exception($"Invalid issuer for {filename}"); | |
} | |
private static void CheckStrongName(ModuleDefinition mdef) | |
{ | |
if (!mdef.Assembly.Name.HasPublicKey || (mdef.Attributes & ModuleAttributes.StrongNameSigned) == 0 ) | |
throw new Exception($"Assembly {mdef.Name} is not strong name signed"); | |
var pkey = ByteToString(mdef.Assembly.Name.PublicKeyToken); | |
if (pkey != VSTUPublicKeyToken) | |
throw new Exception($"Unexpected public key token for assembly {mdef.Name}"); | |
} | |
private static void CheckReferences(ModuleDefinition mdef, Version version) | |
{ | |
foreach(var anref in mdef.AssemblyReferences) | |
{ | |
var pkey = ByteToString(anref.PublicKeyToken); | |
if (pkey != VSPublicKeyToken) | |
continue; | |
if (anref.Version > version) | |
throw new Exception($"Assembly {anref.Name} referenced by {mdef.Name} has invalid version {anref.Version}"); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment