//
.NET Assembly Strong Name Replacer
// (C) 2004 Michael Giagnocavo
// www.atrevido.net
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
public class SNReplace
{
public static void Main( string [] args)
{
if (args.Length < 2 )
{
Console.WriteLine( " Usage: SNReplace <assembly> <keyfile> " );
return ;
}
SNReplace snr = new SNReplace();
snr.AssemblyFile = args[ 0 ];
snr.KeyFile = args[ 1 ];
snr.Replace();
}
public string KeyFile;
public string AssemblyFile;
byte [] currentKey;
byte [] newKey;
byte [] assembly;
private int keyStart;
public void Replace()
{
readKeys();
readAssembly();
findKeyStart();
replaceKey();
save();
resign();
}
private void readKeys()
{
this .currentKey = AssemblyName.GetAssemblyName( this .AssemblyFile).GetPublicKey();
FileStream keyStream = File.OpenRead( this .KeyFile);
this .newKey = new StrongNameKeyPair(keyStream).PublicKey;
keyStream.Close();
}
private void readAssembly()
{
using (FileStream fs = File.OpenRead( this .AssemblyFile))
{
this .assembly = new byte [fs.Length];
fs.Read( this .assembly, 0 , ( int )fs.Length);
}
}
private void findKeyStart()
{
// Yes, it's a slow algorithm.
byte startByte = currentKey[ 0 ];
for ( int i = 0 ; i < this .assembly.Length; i ++ )
{
if (assembly[i] == startByte)
{
// Possible match
if (isKeyFound(i))
{
this .keyStart = i;
return ;
}
}
}
// Not found
Console.WriteLine( " Something's wrong. Public key not found. " );
Environment.Exit( 1 );
}
private bool isKeyFound( int startIndex)
{
for ( int i = 0 ; i < currentKey.Length; i ++ )
{
if (currentKey[i] != assembly[i + startIndex])
{
return false ;
}
}
return true ;
}
private void replaceKey()
{
for ( int i = 0 ; i < newKey.Length; i ++ )
{
assembly[keyStart + i] = newKey[i];
}
}
private void save()
{
using (FileStream fs = File.Create( this .AssemblyFile))
{
fs.Write(assembly, 0 , assembly.Length);
}
}
private void resign()
{
ProcessStartInfo si = new ProcessStartInfo( " sn.exe " );
si.Arguments = string .Format( " -R {0} {1} " , this .AssemblyFile, this .KeyFile);
try
{
Process p = Process.Start(si);
if ( ! p.WaitForExit( 15000 ))
{
Console.WriteLine( " Timeout while waiting for SN to resign the assembly. " );
p.Kill();
Environment.Exit( 2 );
}
}
catch (System.ComponentModel.Win32Exception)
{
Console.WriteLine( " The assembly's public key has been replaced, but SN.exe could not be started. Ensure SN.exe (in the .NET Framework SDK) is in your path, then run SN -R <assembly> <keyfile>. " );
}
}
}
// (C) 2004 Michael Giagnocavo
// www.atrevido.net
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
public class SNReplace
{
public static void Main( string [] args)
{
if (args.Length < 2 )
{
Console.WriteLine( " Usage: SNReplace <assembly> <keyfile> " );
return ;
}
SNReplace snr = new SNReplace();
snr.AssemblyFile = args[ 0 ];
snr.KeyFile = args[ 1 ];
snr.Replace();
}
public string KeyFile;
public string AssemblyFile;
byte [] currentKey;
byte [] newKey;
byte [] assembly;
private int keyStart;
public void Replace()
{
readKeys();
readAssembly();
findKeyStart();
replaceKey();
save();
resign();
}
private void readKeys()
{
this .currentKey = AssemblyName.GetAssemblyName( this .AssemblyFile).GetPublicKey();
FileStream keyStream = File.OpenRead( this .KeyFile);
this .newKey = new StrongNameKeyPair(keyStream).PublicKey;
keyStream.Close();
}
private void readAssembly()
{
using (FileStream fs = File.OpenRead( this .AssemblyFile))
{
this .assembly = new byte [fs.Length];
fs.Read( this .assembly, 0 , ( int )fs.Length);
}
}
private void findKeyStart()
{
// Yes, it's a slow algorithm.
byte startByte = currentKey[ 0 ];
for ( int i = 0 ; i < this .assembly.Length; i ++ )
{
if (assembly[i] == startByte)
{
// Possible match
if (isKeyFound(i))
{
this .keyStart = i;
return ;
}
}
}
// Not found

Console.WriteLine( " Something's wrong. Public key not found. " );
Environment.Exit( 1 );
}
private bool isKeyFound( int startIndex)
{
for ( int i = 0 ; i < currentKey.Length; i ++ )
{
if (currentKey[i] != assembly[i + startIndex])
{
return false ;
}
}
return true ;
}
private void replaceKey()
{
for ( int i = 0 ; i < newKey.Length; i ++ )
{
assembly[keyStart + i] = newKey[i];
}
}
private void save()
{
using (FileStream fs = File.Create( this .AssemblyFile))
{
fs.Write(assembly, 0 , assembly.Length);
}
}
private void resign()
{
ProcessStartInfo si = new ProcessStartInfo( " sn.exe " );
si.Arguments = string .Format( " -R {0} {1} " , this .AssemblyFile, this .KeyFile);
try
{
Process p = Process.Start(si);
if ( ! p.WaitForExit( 15000 ))
{
Console.WriteLine( " Timeout while waiting for SN to resign the assembly. " );
p.Kill();
Environment.Exit( 2 );
}
}
catch (System.ComponentModel.Win32Exception)
{
Console.WriteLine( " The assembly's public key has been replaced, but SN.exe could not be started. Ensure SN.exe (in the .NET Framework SDK) is in your path, then run SN -R <assembly> <keyfile>. " );
}
}
}