程序集强命名替换

// .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>.");
        }
    }
}
posted @ 2009-08-12 09:36 代码乱了 阅读(...) 评论(...) 编辑 收藏