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

时间:2021-07-10 11:23:57

背景:

      1、标题的好像有点长;

      2、这个工具是干什么用的?能看明白标题的人估计能用得上,看懂的估计也不需要。

      3、可以根据签名文件更改、也可以根据程序集文件更改。

      4、欢迎交流,尽请留言。

原始代码:

     

(原).net 程序集重新签名及引用Publickeytoken更改(原).net 程序集重新签名及引用Publickeytoken更改代码
  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  }
244