.net 程序集重新签名及引用Publickeytoken更改

时间:2022-02-12 00:10:44
背景:
      1、标题的好像有点长;
      2、这个工具是干什么用的?能看明白标题的人估计能用得上,看懂的估计也不需要。
      3、可以根据签名文件更改、也可以根据程序集文件更改。
      4、欢迎交流,尽请留言。
原始代码:
代码 
  1 using System;
  2 using System.Linq;
  3 using System.Windows.Forms;
  4 using System.IO;
  5 using Mono.Cecil;
  6 using System.Diagnostics;
  7 using System.Runtime.InteropServices;
  8 using System.Reflection;
  9 namespace AssemblyResign
 10 {
 11     public partial class FormMain : Form
 12     {
 13         public FormMain()
 14         {
 15             InitializeComponent();
 16         }
 17 
 18         private void btnReSign_Click(object sender, EventArgs e)
 19         {
 20             if (tBoxSourceAse.Text == "" && tBoxSourceSign.Text == "")
 21             {
 22                 MessageBox.Show("Please select a source assembly or signfile!", "Error");
 23                 return;
 24             }
 25             if (lBoxObjectAse.Items.Count == 0)
 26             {
 27                 MessageBox.Show("Please select object assembly!", "Error");
 28                 return;
 29             }
 30             AssemblyInfo[] assemblyInfoList = new AssemblyInfo[lBoxObjectAse.Items.Count];
 31             for (int i = 0; i < lBoxObjectAse.Items.Count; i++)
 32             {
 33                 assemblyInfoList[i] = new AssemblyInfo { FileName = lBoxObjectAse.Items[i].ToString() };
 34             }
 35             try
 36             {
 37                 if (tBoxSourceSign.Text != "")
 38                 {
 39                     ReSignByKeyFile(assemblyInfoList, tBoxSourceSign.Text.Trim());
 40                     MessageBox.Show("Resign by signfile ucceed!", "Information");
 41                 }
 42                 else
 43                 {
 44                     ReSignByAssembly(assemblyInfoList, tBoxSourceAse.Text.Trim());
 45                     MessageBox.Show("Resign by assembly ucceed!", "Information");
 46                 }
 47             }
 48             catch(Exception ex)
 49             {
 50                 MessageBox.Show("Resign error,Detail Infor:" + ex.ToString(), "Information");
 51             }
 52             
 53         }
 54         private void btnRelink_Click(object sender, EventArgs e)
 55         {
 56             AssemblyInfo[] assemblyInfoList = new AssemblyInfo[lBoxObjectAse.Items.Count];
 57             for (int i = 0; i < lBoxObjectAse.Items.Count; i++)
 58             {
 59                 assemblyInfoList[i] = new AssemblyInfo { FileName = lBoxObjectAse.Items[i].ToString() };
 60             }
 61             try
 62             {
 63                 ReSignature rs = new ReSignature();
 64                 rs.ReLink(assemblyInfoList, tBoxSourceSign.Text.Trim());
 65                 MessageBox.Show("Relink by singfile succeed!", "Information");
 66             }
 67             catch (Exception ex)
 68             {
 69                 MessageBox.Show("Relink error,Detail Infor:" + ex.ToString(), "Error");
 70             }
 71         }
 72         private void btnSourceAse_Click(object sender, EventArgs e)
 73         {
 74             OpenFileDialog ofd = new OpenFileDialog();
 75             ofd.Filter = "Assembly(*.exe,*.dll)|*.exe;*.dll";
 76             ofd.ShowDialog();
 77             if (ofd.FileName != "")
 78                 tBoxSourceAse.Text = ofd.FileName;
 79         }
 80         private void btnSourceSign_Click(object sender, EventArgs e)
 81         {
 82             OpenFileDialog ofd = new OpenFileDialog();
 83             ofd.Filter = "签名文件(*.snk)|*.snk";
 84             ofd.ShowDialog();
 85             if (ofd.FileName != "")
 86                 tBoxSourceSign.Text = ofd.FileName;
 87         }
 88         private void btnObjectAse_Click(object sender, EventArgs e)
 89         {
 90             OpenFileDialog ofd = new OpenFileDialog();
 91             ofd.Multiselect = true;
 92             ofd.Filter = "应用程序集(*.exe,*.dll)|*.exe;*.dll";
 93             ofd.ShowDialog();
 94             if (ofd.FileNames.Length > 0)
 95             {
 96                 lBoxObjectAse.Items.Clear();
 97                 foreach(string strFileName in ofd.FileNames)
 98                 {
 99                     lBoxObjectAse.Items.Add(strFileName);
100                 }
101             }
102         }
103 
104         private void ReSignByAssembly(AssemblyInfo[] assemblyInfoList, string assemblyFileName)
105         {
106             byte[] publicKey = null;
107             byte[] publicKeyToken = null;
108             Assembly assembly = Assembly.LoadFile(assemblyFileName);
109             publicKey = assembly.GetName().GetPublicKey();
110             publicKeyToken = assembly.GetName().GetPublicKeyToken();
111 
112             foreach (AssemblyInfo assemblyInfo in assemblyInfoList)
113             {
114                 AssemblyDefinition ass = AssemblyFactory.GetAssembly(assemblyInfo.FileName);
115                 ass.Name.PublicKey = publicKey;
116                 ass.Name.PublicKeyToken = publicKeyToken;
117                 AssemblyFactory.SaveAssembly(ass, assemblyInfo.FileName);
118             }
119         }
120         private void ReSignByKeyFile(AssemblyInfo[] assemblyInfoList, string keyFileName)
121         {
122             ReSignature rs = new ReSignature();
123             rs.ReSign(assemblyInfoList, keyFileName);
124         }
125 
126     }
127 
128     #region 重新签名
129     public class ReSignature
130     {
131         [DllImport("mscoree.dll", EntryPoint = "StrongNameKeyDelete", CharSet = CharSet.Auto)]
132         public static extern bool StrongNameKeyDelete(string wszKeyContainer);
133         [DllImport("mscoree.dll", EntryPoint = "StrongNameKeyInstall", CharSet = CharSet.Auto)]
134         public static extern bool StrongNameKeyInstall([MarshalAs(UnmanagedType.LPWStr)] string wszKeyContainer, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2, SizeConst = 0)] byte[] pbKeyBlob, int arg0);
135         [DllImport("mscoree.dll", EntryPoint = "StrongNameSignatureGeneration", CharSet = CharSet.Auto)]
136         public static extern bool StrongNameSignatureGeneration(string wszFilePath, string wszKeyContainer, IntPtr pbKeyBlob, int cbKeyBlob, int ppbSignatureBlob, int pcbSignatureBlob);
137         [DllImport("mscoree.dll", EntryPoint = "StrongNameErrorInfo", CharSet = CharSet.Auto)]
138         public static extern uint StrongNameErrorInfo();
139         [DllImport("mscoree.dll", EntryPoint = "StrongNameTokenFromPublicKey", CharSet = CharSet.Auto)]
140         public static extern bool StrongNameTokenFromPublicKey(byte[] pbPublicKeyBlob, int cbPublicKeyBlob, out IntPtr ppbStrongNameToken, out int pcbStrongNameToken);
141         [DllImport("mscoree.dll", EntryPoint = "StrongNameFreeBuffer", CharSet = CharSet.Auto)]
142         public static extern void StrongNameFreeBuffer(IntPtr pbMemory);
143 
144         private byte[] GetNewKey(string keyFileName)
145         {
146             using (FileStream keyPairStream = File.OpenRead(keyFileName))
147             {
148                 return new StrongNameKeyPair(keyPairStream).PublicKey;
149             }
150         }
151         private byte[] GetPublicKeyToken(string keyFileName)
152         {
153             try
154             {
155                 byte[] newPublicKey;
156                 using (FileStream keyPairStream = File.OpenRead(keyFileName))
157                 {
158                     newPublicKey = new StrongNameKeyPair(keyPairStream).PublicKey;
159                 }
160                 int pcbStrongNameToken;
161                 IntPtr ppbStrongNameToken;
162                 StrongNameTokenFromPublicKey(newPublicKey, newPublicKey.Length, out ppbStrongNameToken, out pcbStrongNameToken);
163                 var token = new byte[pcbStrongNameToken];
164                 Marshal.Copy(ppbStrongNameToken, token, 0, pcbStrongNameToken);
165                 StrongNameFreeBuffer(ppbStrongNameToken);
166                 return token;
167             }
168             catch (Exception)
169             {
170                 return null;
171             }
172         }
173         public void RunSnTool(string assemblyName, string keyFileName)
174         {
175             //SN工具进程            
176             Process snProcess = new Process
177             {
178                 StartInfo =
179                 {
180                     FileName = "SN.exe",
181                     Arguments = string.Format("/Ra {0} {1}", assemblyName, keyFileName)
182                 }
183             };
184             snProcess.Start();
185             snProcess.WaitForExit();
186         }
187         public void ReSign(AssemblyInfo[] assemblyInfoList, string keyFileName)
188         {
189             //用KEY文件建立密钥容器    
190             string wszKeyContainer = Guid.NewGuid().ToString();
191             byte[] pbKeyBlob = File.ReadAllBytes(keyFileName);
192             StrongNameKeyInstall(wszKeyContainer, pbKeyBlob, pbKeyBlob.Length);
193             byte[] publicKey = GetNewKey(keyFileName);
194 
195             foreach (AssemblyInfo assemblyInfo in assemblyInfoList)
196             {
197                 string assemblyName = assemblyInfo.FileName;
198                 AssemblyDefinition asm = AssemblyFactory.GetAssembly(assemblyName);
199                 asm.Name.PublicKey = publicKey;
200                 AssemblyFactory.SaveAssembly(asm, assemblyName);
201                 StrongNameSignatureGeneration(assemblyName, wszKeyContainer, IntPtr.Zero, 0, 0, 0);
202             }
203             //删除新建的密钥容器                     
204             StrongNameKeyDelete(wszKeyContainer);
205         }
206         public void ReLink(AssemblyInfo[] assemblyInfoList, string keyFileName)
207         {
208             byte[] publicKeyToken = GetPublicKeyToken(keyFileName);
209 
210             if (publicKeyToken == null)
211             {
212                 return;
213             }            //初始化一个要重新签名的程序信息列表            
214             //获得每个程序集的名称            
215             foreach (AssemblyInfo assemblyInfo in assemblyInfoList)
216             {
217                 assemblyInfo.FullName = AssemblyFactory.GetAssembly(assemblyInfo.FileName).Name.FullName;
218             }
219             //检查是否被引用,是的话,就替换PublicKeyToken           
220             foreach (AssemblyInfo assemblyInfo in assemblyInfoList)
221             {
222                 AssemblyDefinition assembly = AssemblyFactory.GetAssembly(assemblyInfo.FileName);
223                 foreach (ModuleDefinition module in assembly.Modules)
224 
225                     foreach (AssemblyNameReference reference in module.AssemblyReferences)
226                     {
227                         if (assemblyInfoList.Any(a => a.FullName == reference.FullName))
228                         {
229                             reference.PublicKeyToken = publicKeyToken;
230                             AssemblyFactory.SaveAssembly(assembly, assemblyInfo.FileName);
231                         }
232                     }
233             }
234         }
235     }
236     #endregion
237     
238     public class AssemblyInfo
239     {
240         public string FileName { get; set; }
241         public string FullName { get; set; }
242     }
243 }